我目前正在用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有什么变化吗?我查过了,但在这上面什么也没找到


当前回答

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

activityViewController.popoverPresentationController?.barButtonItem = sender

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

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

从文档到UIPopoverPresentationController:

var barButtonItem: UIBarButtonItem? { get set }

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

其他回答

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

栏按钮项 源视图 源矩形

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

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

我找到了这个解 首先,你呈现弹窗的视图控制器应该实现<UIPopoverPresentationControllerDelegate>协议。

接下来,你需要设置popoverPresentationController的委托。

添加以下功能:

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
// Assuming you've hooked this all up in a Storyboard with a popover presentation style
    if ([segue.identifier isEqualToString:@"showPopover"]) {
        UINavigationController *destNav = segue.destinationViewController;
        PopoverContentsViewController *vc = destNav.viewControllers.firstObject;

        // This is the important part
        UIPopoverPresentationController *popPC = destNav.popoverPresentationController;
        popPC.delegate = self;
    }
}

- (UIModalPresentationStyle)adaptivePresentationStyleForPresentationController: (UIPresentationController *)controller {
    return UIModalPresentationNone;
}

同样的问题也出现在我的项目中,然后我找到了解决方案,在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)
}

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)

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

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

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

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