2015-11-26 29 views
7

Mi sono imbattuto in quella che sembra una situazione che la maggior parte delle persone si trova ad affrontare quando si tenta di presentare uno UIActivityViewController sull'iPad; esso si blocca con:UIActivityViewController che si blocca su iPad con sourceView o barButtonItem

Terminating app due to uncaught exception 'NSGenericException', reason: 'UIPopoverPresentationController (<_UIAlertControllerActionSheetRegularPresentationController: 0x7fc4f2d87d00>) should have a non-nil sourceView or barButtonItem set before the presentation occurs. 

Ecco il mio codice:

- (void)shareLeaflet 
{ 
    NSString *forwardedString = [[NSString alloc] initWithFormat:@"Check out this leaflet\n\n %@ \n\nself.theURLToShare]; 
    UIActivityViewController *activityViewController = nil; 

    if (IDIOM == IPAD) 
    { 
     NSLog(@"iPad"); 
     activityViewController.popoverPresentationController.sourceView = self.view; 
//  activityViewController.popoverPresentationController.sourceRect = self.frame; 
     [self presentViewController:activityViewController 
          animated:YES 
         completion:nil]; 

    } 
    else 
    { 
     NSLog(@"iPhone"); 
     activityViewController = [[UIActivityViewController alloc] initWithActivityItems:[NSArray arrayWithObjects:forwardedString, nil] applicationActivities:nil]; 
     [self presentViewController:activityViewController animated:YES completion:nil]; 


    } 

Nel mio viewDidLoad, ho:

UIBarButtonItem *composeButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAction target:self         action:@selector(shareLeaflet)]; 

    self.navigationItem.rightBarButtonItem = composeButton; 
} 

Questo punto di vista è una UIPageViewController che è in mostra alcune immagini e quando il l'utente preme il pulsante di condivisione, mi aspetto che il foglio di condivisione in stile iOS 8 venga visualizzato. Questo è esattamente ciò che accade su iPhone, ma sull'iPad, continua a bloccarsi. Ciò mi ha portato a Stack Overflow, ma nessuna delle domande (crash on showing UIPopOverPresentationController, iOS Crash: Terminating app due to uncaught exception reason: UIPopoverPresentationController should have a non-nil sourceView, UIWebViewTerminating app due to UIPopoverPresentationController, ios8 iPad uiwebview crashes while displaying popover when user taps drop down list HTML select tag, ecc.) Funziona per me.

Ho provato tutte le soluzioni in là e ho appena ottenuto ciò che è necessario con questo.

questo è quello che sto cercando di realizzare:

enter image description here Ogni pensiero su questo sarebbe molto apprezzato.

risposta

14

Non si sta inizializzando l'attivitàViewController su iPad, quindi sarà sempre nullo.

Prova:

- (void)shareLeaflet 
{ 
    NSString *forwardedString = [[NSString alloc] initWithFormat:@"Check out this leaflet\n\n %@ \n\nself.theURLToShare]; 
    UIActivityViewController *activityViewController = [[UIActivityViewController alloc] initWithActivityItems:[NSArray arrayWithObjects:forwardedString, nil] applicationActivities:nil]; 

    if (IDIOM == IPAD) 
    { 
     NSLog(@"iPad"); 
     activityViewController.popoverPresentationController.sourceView = self.view; 
//  activityViewController.popoverPresentationController.sourceRect = self.frame; 
     [self presentViewController:activityViewController 
          animated:YES 
         completion:nil]; 
    } 
    else 
    { 
     NSLog(@"iPhone"); 
     [self presentViewController:activityViewController 
          animated:YES 
         completion:nil]; 
    } 

E poi per visualizzarlo come nell'immagine: (_shareBarButton è l'UIBarButtonItem che si desidera che il popover per visualizzare da)

- (void)shareLeaflet 
    { 
     NSString *forwardedString = [[NSString alloc] initWithFormat:@"Check out this leaflet\n\n %@ \n\nself.theURLToShare]; 
     UIActivityViewController *activityViewController = [[UIActivityViewController alloc] initWithActivityItems:[NSArray arrayWithObjects:forwardedString, nil] applicationActivities:nil]; 

     if (IDIOM == IPAD) 
     { 
      NSLog(@"iPad"); 
      activityViewController.popoverPresentationController.sourceView = self.view; 
    //  activityViewController.popoverPresentationController.sourceRect = self.frame; 

      _popover = [[UIPopoverController alloc] initWithContentViewController:activityViewController]; 
      _popover.delegate = self; 
      [_popover presentPopoverFromBarButtonItem:_shareBarButton permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES]; 
     } 
     else 
     { 
      NSLog(@"iPhone"); 
      [self presentViewController:activityViewController 
           animated:YES 
          completion:nil]; 
     } 
+0

Ciao @JDx - ah uomo, è stato facile ! Ci scusiamo per la facile domanda lì, che ha funzionato come un fascino! Grazie! Ma solo per fare una domanda di follow-up: posso controllare da che parte arriva il popup? In questo momento, viene dalla parte in alto a sinistra dello schermo, ma il pulsante è in realtà in alto a destra. – amitsbajaj

+0

Nessun problema! Non penso che tu possa, forse potresti usare un UiPopoverController invece? – JDx

+0

Grazie JD - Sto solo provando ad attivare UIActivityViewController, come il foglio di condivisione iOS 8/9. Ho appena aggiornato la domanda per includere un'immagine da Safari sull'iPad: arriva direttamente sotto quel pulsante, ma il mio appare sulla sinistra che è strano – amitsbajaj

1

Si può solo impostare il popoverPresentationControllerbarButtonItem per iPad, ad esempio:

let activityViewController = UIActivityViewController(activityItems: ["Hello, world!", urlString], applicationActivities: nil) 

if UIDevice.current.userInterfaceIdiom == .pad { 
    activityViewController.popoverPresentationController?.barButtonItem = barButtonItem 
} 

self.present(activityViewController, animated: true)