【问题标题】:UIActivityViewController crashing on iPad with sourceView or barButtonItemUIActivityViewController 在 iPad 上使用 sourceView 或 barButtonItem 崩溃
【发布时间】:2016-02-29 19:13:28
【问题描述】:

我遇到了大多数人在 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 等)对我有用。

我已经尝试了那里的所有解决方案,我完全明白了它的要求。

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

对此的任何想法将不胜感激。

【问题讨论】:

    标签: ios objective-c ipad uiwebview uiactivityviewcontroller


    【解决方案1】:

    您没有在 iPad 上初始化 activityViewController,因此它始终为 nil。

    试试:

    - (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];
            }
    

    【讨论】:

    • 嗨@JDx - 啊伙计,这很容易!很抱歉那里有一个简单的问题,这就像一个魅力!谢谢!但只是问一个后续问题 - 我可以控制弹出窗口来自哪一侧吗?现在,它来自屏幕的左上角,但按钮实际上在右上角。
    • 没问题!我不认为你可以,也许你可以使用 UiPopoverController 代替?
    • 感谢 JD - 我只是想激活 UIActivityViewController,就像 iOS 8/9 共享表一样。我刚刚更新了问题以在 iPad 上包含来自 Safari 的图像 - 它直接位于该按钮下方,但我的出现在左侧,这很奇怪
    • 哦,我认为你必须在 UIPopoverController 中显示 activityViewController。我已经用一些代码更新了我的答案。
    • 这就像一个魅力!非常感谢您对此 JDx 的帮助 - 非常感谢! :)
    【解决方案2】:

    您可以只为 iPad 设置popoverPresentationControllerbarButtonItem,例如:

    let activityViewController = UIActivityViewController(activityItems: ["Hello, world!", urlString], applicationActivities: nil)
    
    if UIDevice.current.userInterfaceIdiom == .pad {
        activityViewController.popoverPresentationController?.barButtonItem = barButtonItem
    }
    
    self.present(activityViewController, animated: true)
    

    【讨论】:

      【解决方案3】:

      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)
      

      【讨论】:

        【解决方案4】:

        好吧,我通过简单地检查选择器设法修复了 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)
        

        【讨论】:

          猜你喜欢
          • 2014-10-27
          • 2015-06-15
          • 2015-04-17
          • 1970-01-01
          • 1970-01-01
          • 2012-11-26
          • 2011-04-29
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多