UIActivityViewController crashing on iOS 8 iPads

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


On iPad the activity view controller will be displayed as a popover using the new UIPopoverPresentationController, it requires that you specify an anchor point for the presentation of the popover using one of the three following properties:

  • barButtonItem
  • sourceView
  • sourceRect
  • In order to specify the anchor point you will need to obtain a reference to the UIActivityController's UIPopoverPresentationController and set one of the properties as follows:

    if ( [activityViewController respondsToSelector:@selector(popoverPresentationController)] ) { 
    // iOS8
     activityViewController.popoverPresentationController.sourceView =
    parentView;
     }
    

    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 3

    let imageURL: URL = URL(string: product.images[0].fullImageUrlString)!
    let objectsToShare: [AnyObject] = [imageURL as AnyObject]
    let activityViewController = UIActivityViewController(activityItems: objectsToShare, applicationActivities: nil)
    activityViewController.popoverPresentationController?.sourceView = self.view
    activityViewController.excludedActivityTypes = [ UIActivityType.airDrop]
    self.present(activityViewController, animated: true, completion: nil)
    

    I was encountering this exact problem recently (the original question) in Swift 2.0, where UIActivityViewController worked fine for iPhones, but caused crashes when simulating iPads.

    I just want to add to this thread of answers here that, at least in Swift 2.0, you don't need an if statement. You can just make the popoverPresentationController optional.

    As a quick aside, the accepted answer appears to be saying that you could have just a sourceView, just a sourceRect, or just a barButtonItem, but according to Apple's documentation for UIPopoverPresentationController you need one of the following:

  • barButtonItem
  • sourceView and sourceRect
  • The particular example I was working on is below, where I am creating a function that takes in a UIView (for the sourceView and sourceRect) and String (the UIActivityViewController's sole activityItem).

    func presentActivityViewController(sourceView: UIView, activityItem: String ) {
    
        let activityViewController = UIActivityViewController(activityItems: [activityItem], applicationActivities: [])
    
        activityViewController.popoverPresentationController?.sourceView = sourceView
        activityViewController.popoverPresentationController?.sourceRect = sourceView.bounds
    
        self.presentViewController(activityViewController, animated: true, completion: nil)
    }
    

    This code works on iPhone and iPad (and even tvOS I think) -- if the device does not support popoverPresentationController , the two lines of code that mention it are essentially ignored.

    Kinda nice that all you need to do to make it work for iPads is just add two lines of code, or just one if you're using a barButtonItem!

    链接地址: http://www.djcxy.com/p/44972.html

    上一篇: 为直接的符号化崩溃日志

    下一篇: UIActivityViewController在iOS 8 iPad上崩溃