UIActivityViewController error on iPad using sourceView or barButtonItem

I came across a situation that most people face when trying to present a UIActivityViewController on an iPad; it is crashing:

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

Here is my code:

 - (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]; } 

In my viewDidLoad , I have:

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

This view is a UIPageViewController that shows some images, and when the user clicks the Share button, I expect a pop-up window with an iOS 8 style file. This is exactly what is happening on the iPhone, but on the iPad it continues to crash. This led me to a stack overflow, but none of the questions ( did not work when displaying the UIPopOverPresentationController , iOS Crash: termination of the application due to non-display reason for exception: UIPopoverPresentationController must have an untouched sourceView , UIWebViewTerminating application due to UIPopoverPresentationController , ios8 iPad crashes when ios8 iPad popover, when the user throws a dropdown list HTML select tag , etc.) work for me.

I tried all the solutions there, and I just got what is required with this.

This is what I am trying to achieve:

enter image description here Any thoughts on this would really be appreciated.

+7
ios objective-c ipad uiwebview uiactivityviewcontroller
source share
2 answers

You do not initialize the ActivityViewController on the iPad, so it will always be zero.

Try:

 - (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]; } 

And then, to display it as in the image: (_shareBarButton is the UIBarButtonItem that you want to display the popover)

 - (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]; } 
+14
source share

You can simply set popoverPresentationController barButtonItem for iPad, for example:

 let activityViewController = UIActivityViewController(activityItems: ["Hello, world!", urlString], applicationActivities: nil) if UIDevice.current.userInterfaceIdiom == .pad { activityViewController.popoverPresentationController?.barButtonItem = barButtonItem } self.present(activityViewController, animated: true) 
+1
source share

All Articles