UIActivityViewController crashing on iOS 8 iPads

2019-01-02 19:15发布

I am currently testing my app with Xcode 6 (Beta 6). UIActivityViewController works fine with iPhone devices and simulators but crashes with iPad simulators and devices (iOS 8) with following logs

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

I am using following code for iPhone and iPad for both iOS 7 as well as iOS 8

NSData *myData = [NSData dataWithContentsOfFile:_filename];
NSArray *activityItems = [NSArray arrayWithObjects:myData, nil];
UIActivityViewController *activityViewController = [[UIActivityViewController alloc] initWithActivityItems:nil applicationActivities:nil];
activityViewController.excludedActivityTypes = @[UIActivityTypeCopyToPasteboard];
[self presentViewController:activityViewController animated:YES completion:nil];

I am getting a similar crash in of one my other app as well. Can you please guide me ? has anything changed with UIActivityViewController in iOS 8? I checked but i did not find anything on this

16条回答
ら面具成の殇う
2楼-- · 2019-01-02 20:12

I found this solution Firstly, your view controller that's presenting the popover should implement the <UIPopoverPresentationControllerDelegate> protocol.

Next, you'll need to set the popoverPresentationController's delegate.

Add these functions:

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
// Assuming you've hooked this all up in a Storyboard with a popover presentation style
    if ([segue.identifier isEqualToString:@"showPopover"]) {
        UINavigationController *destNav = segue.destinationViewController;
        PopoverContentsViewController *vc = destNav.viewControllers.firstObject;

        // This is the important part
        UIPopoverPresentationController *popPC = destNav.popoverPresentationController;
        popPC.delegate = self;
    }
}

- (UIModalPresentationStyle)adaptivePresentationStyleForPresentationController: (UIPresentationController *)controller {
    return UIModalPresentationNone;
}
查看更多
刘海飞了
3楼-- · 2019-01-02 20:13

Same problem is come to my project then i found the solution that to open the UIActivityViewController in iPad we have to use UIPopoverController

Here is a code to use it in iPhone and iPad both

//to attach the image and text with sharing 
UIImage *image=[UIImage imageNamed:@"giraffe.png"];
NSString *str=@"Image form My app";
NSArray *postItems=@[str,image];

UIActivityViewController *controller = [[UIActivityViewController alloc] initWithActivityItems:postItems applicationActivities:nil];

//if iPhone
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone) {
    [self presentViewController:controller animated:YES completion:nil];
}
//if iPad
else {
    // Change Rect to position Popover
    UIPopoverController *popup = [[UIPopoverController alloc] initWithContentViewController:controller];
    [popup presentPopoverFromRect:CGRectMake(self.view.frame.size.width/2, self.view.frame.size.height/4, 0, 0)inView:self.view permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
}

For swift 4.2

extension UIViewController {
    func openShareDilog(`with` viewController : UIViewController) {
    let text = "share text will goes here"

    // set up activity view controller
    let textToShare = [text]
    let activityViewController = UIActivityViewController(activityItems: textToShare, applicationActivities: nil)
    activityViewController.popoverPresentationController?.sourceView = self.view // so that iPads won't crash

    activityViewController.excludedActivityTypes = [ UIActivity.ActivityType.airDrop]

    viewController.present(activityViewController, animated: true, completion: nil)
}

}

How to use : Call this function in your viewController

self.openShareDilog(with: self)
查看更多
春风洒进眼中
4楼-- · 2019-01-02 20:13

I tried the next code and it works:

first put a bar button item in your View Controller then create an IBOutlet:

@property(weak,nonatomic)IBOutlet UIBarButtonItem *barButtonItem;

next in the .m file: yourUIActivityViewController.popoverPresentationController.barButtonItem = self.barButtonItem;

查看更多
还给你的自由
5楼-- · 2019-01-02 20:14

Solution using Xamarin.iOS.

In my example I'm doing a screen capture, producing an image, and allowing the user to share the image. The pop up on the iPad is placed about in the middle of the screen.

var activityItems = new NSObject[] { image };
var excludedActivityTypes = new NSString[] {
    UIActivityType.PostToWeibo,
    UIActivityType.CopyToPasteboard,
    UIActivityType.AddToReadingList,
    UIActivityType.AssignToContact,
    UIActivityType.Print,
};
var activityViewController = new UIActivityViewController(activityItems, null);

//set subject line if email is used
var subject = new NSString("subject");
activityViewController.SetValueForKey(NSObject.FromObject("Goal Length"), subject);

activityViewController.ExcludedActivityTypes = excludedActivityTypes;
//configure for iPad, note if you do not your app will not pass app store review
if(null != activityViewController.PopoverPresentationController)
{
    activityViewController.PopoverPresentationController.SourceView = this.View;
    var frame = UIScreen.MainScreen.Bounds;
    frame.Height /= 2;
    activityViewController.PopoverPresentationController.SourceRect = frame;
}
this.PresentViewController(activityViewController, true, null);
查看更多
登录 后发表回答