我目前正在用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 2.0。我发现,如果你试图将弹出窗口锚定在iPad上的共享按钮上,这种方法是有效的。这假设您已经在工具栏中为共享按钮创建了一个出口。
func share(sender: AnyObject) {
let firstActivityItem = "test"
let activityViewController = UIActivityViewController(activityItems: [firstActivityItem], applicationActivities: nil)
if UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiom.Phone {
self.presentViewController(activityViewController, animated: true, completion: nil)
}
else {
if activityViewController.respondsToSelector("popoverPresentationController") {
activityViewController.popoverPresentationController!.barButtonItem = sender as? UIBarButtonItem
self.presentViewController(activityViewController, animated: true, completion: nil)
}
}
}
我看到很多人在使用Swift代码时对iPhone/iPad等进行硬编码。
这是不需要的,你必须使用语言功能。下面的代码假设你将使用一个UIBarButtonItem,并将在iPhone和iPad上工作。
@IBAction func share(sender: AnyObject) {
let vc = UIActivityViewController(activityItems: ["hello"], applicationActivities: nil)
vc.popoverPresentationController?.barButtonItem = sender as? UIBarButtonItem
self.presentViewController(vc, animated: true, completion: nil)
}
注意这里没有If语句或其他疯狂的东西。可选的展开在iPhone上将是nil,所以行vc。popoverpresentationcontroller ?在iphone上没有任何功能。
我最近在Swift 2.0中遇到了这个确切的问题(最初的问题),其中UIActivityViewController在iphone上工作得很好,但在模拟ipad时导致了崩溃。
我只是想在这里补充一点,至少在Swift 2.0中,你不需要if语句。你可以让popoverPresentationController是可选的。
作为一个快速题外话,接受的答案似乎是说,你可以只有一个sourceView,只是一个sourceRect,或只是一个barButtonItem,但根据苹果的文档UIPopoverPresentationController你需要以下之一:
栏按钮项
源视图和源矩形
我正在工作的特定示例如下,在那里我创建了一个函数,接受一个UIView(为sourceView和sourceRect)和字符串(UIActivityViewController的唯一的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)
}
这段代码适用于iPhone和iPad(我认为甚至是tvOS)——如果设备不支持popoverPresentationController,那么提到它的两行代码基本上会被忽略。
有点好,所有你需要做的,使它工作的ipad只是添加两行代码,或者只是一个如果你使用barButtonItem!