我目前正在用Xcode 6 (Beta 6)测试我的应用程序。UIActivityViewController在iPhone设备和模拟器上工作得很好,但在iPad模拟器和设备(iOS 8)上崩溃

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

我使用以下代码用于iPhone和iPad的iOS 7以及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];

我得到一个类似的崩溃在我的另一个应用程序以及。你能引导我吗?ios8中的UIActivityViewController有什么变化吗?我查过了,但在这上面什么也没找到


当前回答

在swift 4下面的代码工作在iphone和ipad。 根据文档

对于给定的设备习惯用法,使用适当的方法来呈现和解散视图控制器是你的责任。在iPad上,你必须在弹出窗口中显示视图控制器。在其他设备上,你必须以模态方式呈现它。

 let activityViewController = UIActivityViewController(activityItems: activityitems, applicationActivities: nil)

    if UIDevice.current.userInterfaceIdiom == .pad {

        if activityViewController.responds(to: #selector(getter: UIViewController.popoverPresentationController)) {
            activityViewController.popoverPresentationController?.sourceView = self.view
        }
    }

    self.present(activityViewController, animated: true, completion: nil)

其他回答

迅速:

    let activityViewController = UIActivityViewController(activityItems: sharingItems, applicationActivities: nil)

    //if iPhone
    if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiom.Phone) {
        self.presentViewController(activityViewController, animated: true, completion: nil)
    } else { //if iPad
        // Change Rect to position Popover
        var popoverCntlr = UIPopoverController(contentViewController: activityViewController)
        popoverCntlr.presentPopoverFromRect(CGRectMake(self.view.frame.size.width/2, self.view.frame.size.height/4, 0, 0), inView: self.view, permittedArrowDirections: UIPopoverArrowDirection.Any, animated: true)

    }

Swift, iOS 9/10 (UIPopoverController弃用后)

let activityViewController = UIActivityViewController(activityItems: sharingItems, applicationActivities: nil)

    if UIDevice.currentDevice().userInterfaceIdiom == .Pad {

       if activityViewController.respondsToSelector(Selector("popoverPresentationController")) {
          activityViewController.popoverPresentationController?.sourceView = self.view
        }
    }

    self.presentViewController(activityViewController, animated: true, completion: nil)

解决Objective-C和使用UIPopoverPresentationController

    UIActivityViewController *controller = /*Init your Controller*/;
    //if iPhone
    if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone) {
        [self presentViewController:controller animated:YES completion:nil];
    }
    //if iPad
    else {
        UIPopoverPresentationController* popOver = controller.popoverPresentationController
        if(popOver){
            popOver.sourceView = controller.view;
            popOver.sourceRect = CGRectMake(self.view.frame.size.width/2, self.view.frame.size.height/4, 0, 0);
            [self presentViewController:controller animated:YES completion:nil];
        }
    }

只是作为参考。

我分享以下代码,这一个使用Swift 5.0。此外,它还避免了弃用的窗口。

UIApplication.shared.windows.first ? .rootViewController !。present(actiycontroller, animated: true, completion: nil)

代码片段如下:

let activityController = UIActivityViewController(activityItems: [activityItem], applicationActivities: nil)

let scenes = UIApplication.shared.connectedScenes 
let windowScene = scenes.first as? UIWindowScene 
let window = windowScene?.windows.first 

if UIDevice.current.userInterfaceIdiom == .pad{
    activityController.popoverPresentationController?.sourceView = window
    activityController.popoverPresentationController?.sourceRect = CGRect(x:  UIScreen.main.bounds.width / 3, y:  UIScreen.main.bounds.height / 1.5, width: 400, height: 400)
}

window?.rootViewController!.present(activityController, animated: true)

它已经在iPhone和iPad上进行了测试。

希望它能帮助到一些人。

干杯!

我使用Swift 5。 当我在iPad上的应用程序中点击“分享按钮”时,我也遇到了同样的问题。找到了这个解。 步骤1:将“view”对象(在对象库中搜索“UIView”)添加到Main.storyboard。 步骤2:在ViewController.swift中创建一个@IBOutlet并分配任意名称(例如:view1)

步骤3:添加上述名称(例如:view1)作为sourceView。这是我的“分享按钮”动作。

@IBAction func Share(_ sender: Any) {
    let activityVC = UIActivityViewController(activityItems: ["www.google.com"], applicationActivities: nil)
    activityVC.popoverPresentationController?.sourceView = view1

    self.present(activityVC, animated: true, completion: nil)


}

我对swift很陌生,在这个问题上耽搁了一个星期。希望这能帮助到一些人。分享这个解。