我目前正在用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代码时对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上没有任何功能。

其他回答

如果你是在iPad上使用swift进行开发,那么你就得小心了,它在调试时可以正常工作,但在发布时就会崩溃。为了让它与testFlight和AppStore一起工作,禁用swift的优化,使用-none进行发布。

我尝试了下一个代码,它工作:

首先在视图控制器中放入一个栏按钮项 然后创建一个IBOutlet:

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

你的uiactivityviewcontroller . popoverpresentationcontroller . barbuttonitem = self.barButtonItem;

在iPad上,活动视图控制器将显示为一个弹出窗口使用新的UIPopoverPresentationController,它要求你指定一个锚点为弹出窗口的表示使用以下三个属性之一:

栏按钮项 源视图 源矩形

为了指定锚点,你需要获得UIActivityController的UIPopoverPresentationController的引用,并设置其中一个属性如下所示:

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

Swift = ios7/ ios8

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

//if iPhone
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiom.Phone) {
    // go on..
} else {
    //if iPad
    if activityViewController.respondsToSelector(Selector("popoverPresentationController")) {
        // on iOS8
        activityViewController.popoverPresentationController!.barButtonItem = self.shareButtonItem;
    }
}
self.presentViewController(activityViewController, animated: true, completion: nil)

如果你在点击UIBarButtonItem时显示UIActivityViewController,请使用以下代码:

activityViewController.popoverPresentationController?.barButtonItem = sender

否则,如果你使用另一个控件,例如UIButton,使用以下代码:

activityViewController.popoverPresentationController?.sourceView = sender
activityViewController.popoverPresentationController?.sourceRect = sender.bounds

从文档到UIPopoverPresentationController:

var barButtonItem: UIBarButtonItem? { get set }

为此属性分配一个值,以将弹出窗口锚定到指定的栏按钮项。显示时,弹出窗口的箭头指向指定的项。或者,您可以使用sourceView和sourceRect属性为弹出窗口指定锚点位置。