热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

UIActivityViewController在iOS8的ipad上崩溃。-UIActivityViewControllercrashingoniOS8iPads

IamcurrentlytestingmyappwithXcode6(Beta6).UIActivityViewControllerworksfinewithiPhone

I am currently testing my app with Xcode 6 (Beta 6). UIActivityViewController works fine with iPhone devices and simulators but crashes with iPad simulators and devices (iOS 8) with following logs

我现在正在用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.'

由于未捕获异常“NSGenericException”而终止应用程序,原因是:“UIPopoverPresentationController (<_UIAlertControllerActionSheetRegularPresentationController: 0x7fc7a874bd90>)应该在呈现之前设置一个非nil sourceView或barButtonItem。”

I am using following code for iPhone and iPad for both iOS 7 as well as iOS 8

我正在为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];

I am getting a similar crash in of one my other app as well. Can you please guide me ? has anything changed with UIActivityViewController in iOS 8? I checked but i did not find anything on this

我的另一个应用程序也有类似的崩溃。你能指导我吗?ios8中的UIActivityViewController有什么变化吗?我查过了,但没有发现任何线索

15 个解决方案

#1


429  

On iPad the activity view controller will be displayed as a popover using the new UIPopoverPresentationController, it requires that you specify an anchor point for the presentation of the popover using one of the three following properties:

在iPad上,activity视图控制器将显示为一个使用新的UIPopoverPresentationController的弹出窗口,它要求您指定一个锚点来使用以下三个属性中的一个来表示弹出窗口。

  • barButtonItem
  • sourceView
  • sourceView
  • sourceRect
  • sourceRect

In order to specify the anchor point you will need to obtain a reference to the UIActivityController's UIPopoverPresentationController and set one of the properties as follows:

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

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

#2


166  

Same problem is come to my project then i found the solution that to open the UIActivityViewController in iPad we have to use UIPopoverController

同样的问题也出现在我的项目中然后我找到了解决方案要在iPad中打开UIActivityViewController我们必须使用UIPopoverController

Here is a code to use it in iPhone and iPad both

这是在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];
}

For swift

为迅速

let imageURL: URL = URL(string: product.images[0].fullImageUrlString)!
let objectsToShare: [AnyObject] = [imageURL as AnyObject]
let activityViewCOntroller= UIActivityViewController(activityItems: objectsToShare, applicationActivities: nil)
activityViewController.popoverPresentationController?.sourceView = self.view
activityViewController.excludedActivityTypes = [.airDrop]
self.present(activityViewController, animated: true, completion: nil)

#3


35  

I was encountering this exact problem recently (the original question) in Swift 2.0, where UIActivityViewController worked fine for iPhones, but caused crashes when simulating iPads.

我最近在Swift 2.0中遇到了这个问题(最初的问题),UIActivityViewController在iphone上工作得很好,但在模拟ipad时却导致了崩溃。

I just want to add to this thread of answers here that, at least in Swift 2.0, you don't need an if statement. You can just make the popoverPresentationController optional.

我只是想补充一下,至少在Swift 2.0中,不需要if语句。可以将popoverPresentationController设置为可选。

As a quick aside, the accepted answer appears to be saying that you could have just a sourceView, just a sourceRect, or just a barButtonItem, but according to Apple's documentation for UIPopoverPresentationController you need one of the following:

顺便说一句,公认的答案似乎是你可以有一个sourceView,一个sourceRect,或者一个barButtonItem,但是根据苹果的UIPopoverPresentationController文档,你需要以下其中一个:

  • barButtonItem
  • sourceView and sourceRect
  • sourceView和sourceRect

The particular example I was working on is below, where I am creating a function that takes in a UIView (for the sourceView and sourceRect) and String (the UIActivityViewController's sole activityItem).

我正在处理的特定示例在下面,我正在创建一个函数,它接收UIView(用于sourceView和sourceRect)和String (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)
}

This code works on iPhone and iPad (and even tvOS I think) -- if the device does not support popoverPresentationController, the two lines of code that mention it are essentially ignored.

这段代码适用于iPhone和iPad(我想甚至是tvOS)——如果设备不支持popoverPresentationController,那么提到它的两行代码基本上就会被忽略。

Kinda nice that all you need to do to make it work for iPads is just add two lines of code, or just one if you're using a barButtonItem!

让ipad运行所需要做的就是添加两行代码,或者如果你使用barButtonItem,只添加一行代码就可以了。

#4


16  

I see a lot of people hardcoding iPhone/iPad etc. while using Swift code.

我看到很多人在使用Swift代码时硬编码iPhone/iPad等。

This is not needed, you have to use the language features. The following code assumes you will use a UIBarButtonItem and will work on both iPhone and 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)
 }

Notice how there are no If statements or any other crazy thing. The optional unwrapping will be nil on iPhone, so the line vc.popoverPresentationController? will not do anything on iPhones.

注意这里没有If语句或其他疯狂的东西。在iPhone上,可选的取消包装将是nil,因此,行vc.popoverPresentationController?不会在iphone上做任何事情。

#5


10  

Solution using Xamarin.iOS.

使用Xamarin.iOS解决方案。

In my example I'm doing a screen capture, producing an image, and allowing the user to share the image. The pop up on the iPad is placed about in the middle of the screen.

在我的示例中,我正在执行屏幕捕获、生成图像并允许用户共享图像。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);

#6


6  

Swift, iOS 9/10 (after UIPopoverController deprecated)

Swift, ios9 /10(在反对UIPopoverController之后)

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

    if UIDevice.currentDevice().userInterfaceIdiom == .Pad {

       if activityViewController.respondsToSelector(Selector("popoverPresentationController")) {
          activityViewController.popoverPresentationController?.sourceView = self.view
        }
    }

    self.presentViewController(activityViewController, animated: true, completion: nil)

#7


5  

In Swift to fix this for iPad, best way is to do like this I found.

在快速修复iPad的过程中,最好的方法就是像我发现的那样。

    let things = ["Things to share"]
    let avc = UIActivityViewController(activityItems:things, applicationActivities:nil)
    avc.setValue("Subject title", forKey: "subject")
    avc.completiOnWithItemsHandler= {
        (s: String!, ok: Bool, items: [AnyObject]!, err:NSError!) -> Void in
    }

    self.presentViewController(avc, animated:true, completion:nil)
    if let pop = avc.popoverPresentationController {
        let v = sender as! UIView // sender would be the button view tapped, but could be any view
        pop.sourceView = v
        pop.sourceRect = v.bounds
    }

#8


4  

Fix for Swift 2.0

修复迅速2.0

    if UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiom.Phone {
        self.presentViewController(activityVC, animated: true, completion: nil)
    }
    else {
        let popup: UIPopoverCOntroller= UIPopoverController(contentViewController: activityVC)
        popup.presentPopoverFromRect(CGRectMake(self.view.frame.size.width / 2, self.view.frame.size.height / 4, 0, 0), inView: self.view, permittedArrowDirections: UIPopoverArrowDirection.Any, animated: true)
    }

#9


3  

Swift:

迅速:

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

    //if iPhone
    if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiom.Phone) {
        self.presentViewController(activityViewController, animated: true, completion: nil)
    } else { //if iPad
        // Change Rect to position Popover
        var popoverCntlr = UIPopoverController(contentViewController: activityViewController)
        popoverCntlr.presentPopoverFromRect(CGRectMake(self.view.frame.size.width/2, self.view.frame.size.height/4, 0, 0), inView: self.view, permittedArrowDirections: UIPopoverArrowDirection.Any, animated: true)

    }

#10


3  

Swift 3:

斯威夫特3:

class func openShareActions(image: UIImage, vc: UIViewController) {
    let activityVC = UIActivityViewController(activityItems: [image], applicationActivities: nil)
    if UIDevice.current.userInterfaceIdiom == .pad {
        if activityVC.responds(to: #selector(getter: UIViewController.popoverPresentationController)) {
            activityVC.popoverPresentationController?.sourceView = vc.view
        }
    }
    vc.present(activityVC, animated: true, completion: nil)
}

#11


1  

swift = ios7/ ios8

斯威夫特= 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)

#12


0  

I found this solution Firstly, your view controller that's presenting the popover should implement the protocol.

我首先找到了这个解决方案,呈现弹窗的视图控制器应该实现 协议。

Next, you'll need to set the popoverPresentationController's delegate.

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

Add these functions:

添加这些功能:

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

#13


0  

I tried the next code and it works:

我尝试了下一个代码,它成功了:

first put a bar button item in your View Controller then create an IBOutlet:

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

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

@ property(弱,原子)把IBOutlet UIBarButtonItem *;

next in the .m file: yourUIActivityViewController.popoverPresentationController.barButtOnItem= self.barButtonItem;

接下来在.m文件中:yourUIActivityViewController.popoverPresentationController。把= self.barButtonItem;

#14


-1  

For Swift 2.0. I found that this works if you are trying to anchor the popover to a share button on iPad. This assumes that you have created an outlet for the share button in your tool bar.

2.0迅速。我发现,如果你想把弹出窗口固定在iPad上的一个共享按钮上,这个功能就会起作用。这假定您已经为工具栏中的共享按钮创建了一个outlet。

func share(sender: AnyObject) {
    let firstActivityItem = "test"

    let activityViewCOntroller= UIActivityViewController(activityItems: [firstActivityItem], applicationActivities: nil)

    if UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiom.Phone {
        self.presentViewController(activityViewController, animated: true, completion: nil)
    }
    else {            
        if activityViewController.respondsToSelector("popoverPresentationController") {
            activityViewController.popoverPresentationController!.barButtOnItem= sender as? UIBarButtonItem
            self.presentViewController(activityViewController, animated: true, completion: nil)
        }

    }
}

#15


-5  

Be careful if you are developing for iPad using swift, it will work fine in debug, but will crash in release. In order to make it work with testFlight and AppStore, disable optimization for swift using -none for release.

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


推荐阅读
author-avatar
L鸿玖
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有