UIActivityViewController crashing on iPad with sourceView or barButtonItem
best solve for iPad & iPhone iOS 14.4
let urlstring = "https://apps.apple.com/ae/app/"
let text = "some text for your app"
let url = NSURL(string: urlstring)
let textToShare = [url!,text] as [Any]
let activityViewController = UIActivityViewController(activityItems: textToShare as [Any], applicationActivities: nil)
activityViewController.excludedActivityTypes = [ UIActivity.ActivityType.airDrop, UIActivity.ActivityType.postToFacebook ,UIActivity.ActivityType.postToFlickr,UIActivity.ActivityType.postToTwitter,UIActivity.ActivityType.postToVimeo,UIActivity.ActivityType.mail,UIActivity.ActivityType.addToReadingList]
activityViewController.popoverPresentationController?.sourceView = self.view
activityViewController.popoverPresentationController?.sourceRect = view.bounds
activityViewController.popoverPresentationController?.permittedArrowDirections = UIPopoverArrowDirection.down
UIApplication.shared.windows.first?.rootViewController?.present(activityViewController, animated: true, completion: nil)
You aren't initialising the activityViewController on iPad so it will always be nil.
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 like in the image: (_shareBarButton is the UIBarButtonItem that you want the popover to display from)
- (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];
}
You can just set the popoverPresentationController
's 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)