我目前正在用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)
使用Xamarin.iOS解决方案。
在我的示例中,我正在进行屏幕捕获,生成图像,并允许用户共享图像。iPad上的弹出窗口位于屏幕中间。
var activityItems = new NSObject[] { image };
var excludedActivityTypes = new NSString[] {
UIActivityType.PostToWeibo,
UIActivityType.CopyToPasteboard,
UIActivityType.AddToReadingList,
UIActivityType.AssignToContact,
UIActivityType.Print,
};
var activityViewController = new UIActivityViewController(activityItems, null);
//set subject line if email is used
var subject = new NSString("subject");
activityViewController.SetValueForKey(NSObject.FromObject("Goal Length"), subject);
activityViewController.ExcludedActivityTypes = excludedActivityTypes;
//configure for iPad, note if you do not your app will not pass app store review
if(null != activityViewController.PopoverPresentationController)
{
activityViewController.PopoverPresentationController.SourceView = this.View;
var frame = UIScreen.MainScreen.Bounds;
frame.Height /= 2;
activityViewController.PopoverPresentationController.SourceRect = frame;
}
this.PresentViewController(activityViewController, true, null);
我最近在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!
同样的问题也出现在我的项目中,然后我找到了解决方案,在iPad中打开UIActivityViewController,我们必须使用UIPopoverController
下面是在iPhone和iPad上使用它的代码:
//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];
}
对于swift 4.2 / swift 5
func openShareDilog() {
let text = "share text will goes here"
// set up activity view controller
let textToShare = [text]
let activityViewController = UIActivityViewController(activityItems: textToShare, applicationActivities: nil)
activityViewController.excludedActivityTypes = [.airDrop]
if let popoverController = activityViewController.popoverPresentationController {
popoverController.sourceRect = CGRect(x: UIScreen.main.bounds.width / 2, y: UIScreen.main.bounds.height / 2, width: 0, height: 0)
popoverController.sourceView = self.view
popoverController.permittedArrowDirections = UIPopoverArrowDirection(rawValue: 0)
}
self.present(activityViewController, animated: true, completion: nil)
}