14

Ho creato un'app per iPhone. Ora, lo sto ricreando per iPad.UIActivityViewController richiede molto tempo per presentare

Quando l'utente seleziona il pulsante di azione nella barra degli strumenti, un popover dovrebbe mostrare con un UIActivityViewController, ma per qualche motivo, ci vogliono circa 10 secondi per farlo visualizzare la prima volta. Su iPhone, ci vuole circa un secondo. È lo stesso codice tranne che per il popover.

Ho provato a disabilitare il popover, ma ci vogliono ancora circa 10 secondi per essere mostrato.

Ecco il codice:

-(IBAction)Actions:(UIBarButtonItem*)sender 
{ 
    if ([activityPopover isPopoverVisible] == YES) 
    { 
     [activityPopover dismissPopoverAnimated:YES]; 
     return; 
    } 
    UIWebView *currentWebView = ((TabView *)self.tabs[self.currentTabIndex]).webViewObject; 

    NSString *currentURL = (NSString*)[currentWebView request].mainDocumentURL; 
    if (currentURL == NULL) return; 

    BookmarkActivity *bookmarkActivity = [[BookmarkActivity alloc] init]; 

    UIActivityViewController *sharing = [[UIActivityViewController alloc] initWithActivityItems:[NSArray arrayWithObject:currentURL] applicationActivities:@[bookmarkActivity]]; 

    activityPopover = [[UIPopoverController alloc] initWithContentViewController:sharing]; 
    [activityPopover presentPopoverFromBarButtonItem:sender permittedArrowDirections:UIPopoverArrowDirectionUp animated:YES];  
} 

Ho testato sul mio iPad 3 e il mio iPad mini, sia prendere un po 'di presentare questo.

Come posso risolvere il problema?

+0

Avete provato con il tempo profiler? Potresti scoprire quali sono le istruzioni che richiedono la maggior parte del tempo. –

+0

No, come faccio? – Maximilian

+0

Premere cmd + I quindi selezionare il profiler temporale. Aspettare per 10-20 secondi. Quindi selezionare l'opzione "nascondi librerie di sistema". Ciò consentirà di vedere meglio il metodo nello stack di chiamate. Trovare il metodo nello stack di chiamate e fare clic due volte su di esso, vedrai il consumo di tempo. –

risposta

18

Buona domanda, ho appena avuto lo stesso problema. Non è davvero risolvibile. Tuttavia, è possibile migliorare l'esperienza degli utenti con la creazione di un indicatore di attività e quindi l'invio l'inizializzazione del UIActivityViewController allo sfondo:

-(void)openIn:(id)sender 
{ 
    // start activity indicator 
    [self.activityIndicator startAnimating]; 

    // create new dispatch queue in background 
    dispatch_queue_t queue = dispatch_queue_create("openActivityIndicatorQueue", NULL); 

    // send initialization of UIActivityViewController in background 
    dispatch_async(queue, ^{ 
     NSArray *dataToShare = @[@"MyData"]; 
     UIActivityViewController *activityViewController = [[UIActivityViewController alloc] initWithActivityItems:dataToShare applicationActivities:nil]; 

     // when UIActivityViewController is finally initialized, 
     // hide indicator and present it on main thread 
     dispatch_async(dispatch_get_main_queue(), ^{ 
      [self.activityIndicator stopAnimating]; 
      [self presentViewController:activityViewController animated:YES completion:nil]; 
     }); 
    }); 
} 

Funziona come un fascino. Quando l'utente tocca il pulsante, l'indicatore di attività inizia a animare, indicando che il processo richiederà un po 'di tempo.

+2

Suggerisco lo stesso, ma in modo più elegante. Imposta la proprietà 'UIBarButtonItem'' customView' su 'UIActivityIndicator' creata al volo. Sostituisce l'icona del pulsante con l'indicatore di attività. Quindi, sul blocco di completamento della chiamata di animazione della presentazione '[button setCustomView: nil]' e ritornerà allo stile originale. =) –

+0

@BrunoPhilipe su iOS 7.0.3 Chiamando 'setCustomView: nil' su un UIBarButtonItem creato con un'icona di sistema appare per rimuovere completamente l'icona. – zekel

+0

@zeckel Sto facendo su un'applicazione con iOS 7.1 beta e funziona correttamente. Forse è qualcos'altro? Se il tuo pulsante ha usato una vista personalizzata prima di fare la sostituzione, devi invece sostituirla invece di impostarla su 'nil'. Prova a controllare il valore precedente di 'customView'. –

13

Avevo lo stesso problema su iOS 7. Quando ho rimosso UIActivityTypeAirDrop dai tipi di attività consentiti, tuttavia, il controller appare quasi istantaneamente.

+0

Questo è strano, e triste che Apple non possa farlo velocemente: O grazie! – Maximilian

+5

È più veloce di prima ma è ancora lento – Gabox

+3

Codice corrispondente: UIActivityViewController * activityController = [[UIActivityViewController alloc] initWithActivityItems: sharedItems applicationActivities: nil]; activityController.excludedActivityTypes = @ [UIActivityTypeAirDrop]; – Beninho85

5

Anche se queste chiamate sono già dal thread principale, dal momento che iOS 7, avvolgendo alcune di queste chiamate di presentazione in un blocco dispaccio sembra ridurre notevolmente il ritardo

dispatch_async(dispatch_get_main_queue(), ^{ 
    [self presentViewController:activityViewController animated:YES completion:nil]; 
}); 
+0

Lo hai misurato? Riesco a malapena a capire come dovrebbe funzionare, poiché esegue semplicemente la presentazione nella successiva iterazione del mainloop, cioè in realtà _later_ rispetto a quando la si chiama direttamente. *perplesso* – DrMickeyLauer