Sharing via UIActivityViewController to Twitter/Facebook etc. causing crash

后端 未结 5 1183
野的像风
野的像风 2020-12-06 02:10

On iOS8 I\'m using a UIActivityViewController to share a UIImage to Facebook/Twitter etc. It seemed to be working fine, but today it suddenly started crashing when running t

相关标签:
5条回答
  • 2020-12-06 02:42

    Here is how I solved with swift:

        let someText:String = "shareText"
        let google:NSURL = NSURL(string:"http://google.com")!
    
        let activityViewController = UIActivityViewController(activityItems: [someText, google], applicationActivities: nil)
    
        if respondsToSelector("popoverPresentationController") {
            self.senderView.presentViewController(activityViewController, animated: true, completion: nil)
            activityViewController.popoverPresentationController?.sourceView = sender
        }else{
            senderView.presentViewController(activityViewController, animated: true, completion: nil)
        }
    
    0 讨论(0)
  • 2020-12-06 02:44

    Swift 5 - Copy from Working Project

    Problem

    If you present UIActivityViewController for sharing in the following way, your app will work correctly but it will crash on iPad devices.

    func shareSiteURL()
    {
        let title = "My app"
        let url = URL(string: "https://myWebSite.com")
    
        let activityController = UIActivityViewController(activityItems: [url!, title], applicationActivities: nil)
        self.present(activityController, animated: true, completion: nil)
    }
    

    Explanation

    When you presented UIActivityViewController on the iPad, the iPad presents the activity controller as a popover controller and hence it needs to know and use the source view. On the previous code, we did not pass the source view in case if the device is an iPad and that is why the app crashed when running on iPad.

    Solution

    To solve this issue, we are going to check if the controller is presented as a popover (the app is running on iPad) and if so, we will pass the source view otherwise the app will crash.

    func shareSiteURL()
    {
        let title = "My app"
        let url = URL(string: "https://myWebSite.com")
    
        // check if the controller is presented as a popover (the app is running on iPad)
        // and if so, we will pass the source view otherwise the app will crash.
    
        if let popoverController = activityController.popoverPresentationController
        {
            popoverController.sourceView = viewController.view
        }
    
        let activityController = UIActivityViewController(activityItems: [url!, title], applicationActivities: nil)
        self.present(activityController, animated: true, completion: nil)
    }
    
    0 讨论(0)
  • 2020-12-06 02:53

    popoverPresentationController was new to iOS 8 and will crash on iOS 7. It'll also be nil on iPhone because it's only in a UIPopover on iPad. Here's Christian's answer in Swift, with those facts taken into account:

    Swift 2.0 (Xcode 7)

    let controller = UIActivityViewController(activityItems: [text, url, myImage], applicationActivities: nil)
    
    presentViewController(controller, animated: true, completion: nil)
    
    if #available(iOS 8.0, *) {
        let presentationController = controller.popoverPresentationController
        presentationController?.sourceView = view
    }
    

    Swift 1.2 (Xcode 6)

    let controller = UIActivityViewController(activityItems: [text, url, myImage], applicationActivities: nil)
    
    presentViewController(controller, animated: true, completion: nil)
    
    if controller.respondsToSelector("popoverPresentationController") {
        // iOS 8+
        let presentationController = controller.popoverPresentationController
        presentationController?.sourceView = view
    }
    
    0 讨论(0)
  • 2020-12-06 02:58

    Looking at the docs, I needed to define a source view for the popover controller

    UIActivityViewController *controller =
    [[UIActivityViewController alloc]
     initWithActivityItems:@[text,url,myImage]
     applicationActivities:nil];
    
    [self presentViewController:controller animated:YES completion:nil];
    
    UIPopoverPresentationController *presentationController =
    [controller popoverPresentationController];
    
    presentationController.sourceView = self.view;
    
    0 讨论(0)
  • 2020-12-06 03:01

    As @mmccomb told here, on iPad the activity view controller will be displayed as a popover using the new UIPopoverPresentationController. You need to specify at least the source view:

    activityViewController.popoverPresentationController.sourceView = YOURDESIREDVIEW;
    

    If you want to show the popover anchored to any point to that view, specify it with the sourceRect property of the popoverPresentationController.

    0 讨论(0)
提交回复
热议问题