使用sourceView或barButtonItem

时间:2015-11-26 16:07:30

标签: ios objective-c ipad uiwebview uiactivityviewcontroller

我遇到了大多数人在试图在iPad上展示UIActivityViewController时所面临的情况;它崩溃了:

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

这是我的代码:

- (void)shareLeaflet
{
    NSString *forwardedString = [[NSString alloc] initWithFormat:@"Check out this leaflet\n\n %@ \n\nself.theURLToShare];
    UIActivityViewController *activityViewController = nil;

    if (IDIOM == IPAD)
    {
        NSLog(@"iPad");
        activityViewController.popoverPresentationController.sourceView = self.view;
//        activityViewController.popoverPresentationController.sourceRect = self.frame;
        [self presentViewController:activityViewController
                           animated:YES
                         completion:nil];

    }
    else
    {
        NSLog(@"iPhone");
        activityViewController = [[UIActivityViewController alloc] initWithActivityItems:[NSArray arrayWithObjects:forwardedString, nil] applicationActivities:nil];
        [self presentViewController:activityViewController animated:YES completion:nil];


    }

在我的viewDidLoad中,我有:

UIBarButtonItem *composeButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAction target:self                                    action:@selector(shareLeaflet)];

    self.navigationItem.rightBarButtonItem = composeButton;
}

这个视图是UIPageViewController,它展示了一些图像,当用户点击分享按钮时,我希望弹出iOS 8样式的共享表。这正是iPhone上发生的事情,但在iPad上,它仍在继续崩溃。这导致我发现Stack Overflow,但没有一个问题(crash on showing UIPopOverPresentationControlleriOS Crash: Terminating app due to uncaught exception reason: UIPopoverPresentationController should have a non-nil sourceViewUIWebViewTerminating app due to UIPopoverPresentationControllerios8 iPad uiwebview crashes while displaying popover when user taps drop down list HTML select tag等等对我有用。

我已经尝试了所有的解决方案,我只是完全得到了这个所需要的。

这就是我想要实现的目标:

enter image description here 对此的任何想法都会非常感激。

4 个答案:

答案 0 :(得分:15)

你没有在iPad上初始化activityViewController,所以它总是零。

尝试:

- (void)shareLeaflet
{
    NSString *forwardedString = [[NSString alloc] initWithFormat:@"Check out this leaflet\n\n %@ \n\nself.theURLToShare];
    UIActivityViewController *activityViewController = [[UIActivityViewController alloc] initWithActivityItems:[NSArray arrayWithObjects:forwardedString, nil] applicationActivities:nil];

    if (IDIOM == IPAD)
    {
        NSLog(@"iPad");
        activityViewController.popoverPresentationController.sourceView = self.view;
//        activityViewController.popoverPresentationController.sourceRect = self.frame;
        [self presentViewController:activityViewController
                           animated:YES
                         completion:nil];
    }
    else
    {
        NSLog(@"iPhone");
        [self presentViewController:activityViewController 
                          animated:YES 
                        completion:nil];
    }

然后像在图像中一样显示:( _shareBarButton是您希望弹出框显示的UIBarButtonItem)

- (void)shareLeaflet
    {
        NSString *forwardedString = [[NSString alloc] initWithFormat:@"Check out this leaflet\n\n %@ \n\nself.theURLToShare];
        UIActivityViewController *activityViewController = [[UIActivityViewController alloc] initWithActivityItems:[NSArray arrayWithObjects:forwardedString, nil] applicationActivities:nil];

        if (IDIOM == IPAD)
        {
            NSLog(@"iPad");
            activityViewController.popoverPresentationController.sourceView = self.view;
    //        activityViewController.popoverPresentationController.sourceRect = self.frame;

           _popover = [[UIPopoverController alloc] initWithContentViewController:activityViewController];
           _popover.delegate = self;
           [_popover presentPopoverFromBarButtonItem:_shareBarButton permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
        }
        else
        {
            NSLog(@"iPhone");
            [self presentViewController:activityViewController 
                              animated:YES 
                            completion:nil];
        }

答案 1 :(得分:2)

您可以为iPad设置popoverPresentationController&#39; barButtonItem,例如:

let activityViewController = UIActivityViewController(activityItems: ["Hello, world!", urlString], applicationActivities: nil)

if UIDevice.current.userInterfaceIdiom == .pad {
    activityViewController.popoverPresentationController?.barButtonItem = barButtonItem
}

self.present(activityViewController, animated: true)

答案 2 :(得分:0)

好吧,我通过简单地检查选择器设法修复了 iPad 上的崩溃: 让activityVC = UIActivityViewController(activityItems: objectsToShare, applicationActivities: nil)

        if activityVC.responds(to: #selector(getter: self.popoverPresentationController)) {
            activityVC.popoverPresentationController?.barButtonItem = sender
        }
        self.present(activityVC, animated: true, completion: nil)

答案 3 :(得分:0)

iPad 和 iPhone iOS 14.4 的最佳解决方案

let urlstring = "https://apps.apple.com/ae/app/"
let text = "some text for your app"
let url = NSURL(string: urlstring)
let textToShare = [url!,text] as [Any]
let activityViewController = UIActivityViewController(activityItems: textToShare as [Any], applicationActivities: nil)
    
activityViewController.excludedActivityTypes = [ UIActivity.ActivityType.airDrop, UIActivity.ActivityType.postToFacebook ,UIActivity.ActivityType.postToFlickr,UIActivity.ActivityType.postToTwitter,UIActivity.ActivityType.postToVimeo,UIActivity.ActivityType.mail,UIActivity.ActivityType.addToReadingList]

activityViewController.popoverPresentationController?.sourceView = self.view
activityViewController.popoverPresentationController?.sourceRect = view.bounds
activityViewController.popoverPresentationController?.permittedArrowDirections = UIPopoverArrowDirection.down
UIApplication.shared.windows.first?.rootViewController?.present(activityViewController, animated: true, completion: nil)