UIAlertController崩溃(iPad)

我正在使用Xcode 6开发iOS应用程序。

当我使用UIAlertController ,它可以在iPhone 6模拟器上运行,但在iPad模拟器上崩溃。

我的问题,同时点击“分享”,然后它可能会坠毁。 我怎么能解决它?

这是我的代码:

 override func tableView(tableView: UITableView, editActionsForRowAtIndexPath indexPath: NSIndexPath) -> [AnyObject] { var shareAction = UITableViewRowAction(style: UITableViewRowActionStyle.Default, title: "Share", handler: { (action:UITableViewRowAction!, indexPath:NSIndexPath!) -> Void in let shareMenu = UIAlertController(title: nil, message: "Share using", preferredStyle: .ActionSheet) let twitterAction = UIAlertAction(title: "Twitter", style: UIAlertActionStyle.Default, handler: nil) let facebookAction = UIAlertAction(title: "Facebook", style: UIAlertActionStyle.Default, handler: nil) let emailAction = UIAlertAction(title: "Email", style: UIAlertActionStyle.Default, handler: nil) let cancelAction = UIAlertAction(title: "Cancel", style: UIAlertActionStyle.Cancel, handler: nil) shareMenu.addAction(twitterAction) shareMenu.addAction(facebookAction) shareMenu.addAction(emailAction) shareMenu.addAction(cancelAction) self.presentViewController(shareMenu, animated: true, completion: nil) } ) 

Xcode显示了这个消息:

 ******Terminating app due to uncaught exception 'NSGenericException', reason: 'Your application has presented a UIAlertController (<UIAlertController: 0xaf71c80>) of style UIAlertControllerStyleActionSheet. The modalPresentationStyle of a UIAlertController with this style is UIModalPresentationPopover. You must provide location information for this popover through the alert controller's popoverPresentationController. You must provide either a sourceView and sourceRect or a barButtonItem. If this information is not known when you[![enter image description here][1]][1] present the alert controller, you may provide it in the UIPopoverPresentationControllerDelegate method -prepareForPopoverPresentation.' *** First throw call stack: ( 0 CoreFoundation 0x0023c746 __exceptionPreprocess + 182 1 libobjc.A.dylib 0x01c7aa97 objc_exception_throw + 44 2 UIKit 0x012c4062 -[UIPopoverPresentationController presentationTransitionWillBegin] + 3086 3 UIKit 0x00bda174 __71-[UIPresentationController _initViewHierarchyForPresentationSuperview:]_block_invoke + 1549 4 UIKit 0x00bd8247 __56-[UIPresentationController runTransitionForCurrentState]_block_invoke + 198 5 UIKit 0x00c0d31b __40+[UIViewController _scheduleTransition:]_block_invoke + 18 6 UIKit 0x00ac6862 ___afterCACommitHandler_block_invoke + 15 7 UIKit 0x00ac680d _applyBlockToCFArrayCopiedToStack + 415 8 UIKit 0x00ac6622 _afterCACommitHandler + 549 9 CoreFoundation 0x0015d86e __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 30 10 CoreFoundation 0x0015d7b0 __CFRunLoopDoObservers + 400 11 CoreFoundation 0x001531ea __CFRunLoopRun + 1226 12 CoreFoundation 0x00152a5b CFRunLoopRunSpecific + 443 13 CoreFoundation 0x0015288b CFRunLoopRunInMode + 123 14 GraphicsServices 0x047b82c9 GSEventRunModal + 192 15 GraphicsServices 0x047b8106 GSEventRun + 104 16 UIKit 0x00a9c106 UIApplicationMain + 1526 17 Mars I 0x0001c724 main + 180 18 libdyld.dylib 0x02392ac9 start + 1 19 ??? 0x00000001 0x0 + 1 ) libc++abi.dylib: terminating with uncaught exception of type NSException****** 

为了保持设备的独立性,请使用它,如下面的代码片段所示。 这个代码将返回nil在iPhone / compact尺寸设备上的popoverPresentationController,所以你可以安全地在通用项目中使用它。

 if let popoverPresentationController = shareMenu.popoverPresentationController { popoverPresentationController.sourceView = self.view popoverPresentationController.sourceRect = sender.bounds } self.presentViewController(shareMenu, animated: true, completion: nil) 

试试这个代码:

 shareMenu.popoverPresentationController.sourceView = self.view shareMenu.popoverPresentationController.sourceRect = CGRectMake(self.view.bounds.size.width / 2.0, self.view.bounds.size.height / 2.0, 1.0, 1.0) self.presentViewController(shareMenu, animated: true, completion: nil) 

我使用这个方便的扩展来创build不会崩溃的操作表

 extension UIAlertController { class func actionSheetWith(title: String?, message: String?, sourceView: UIView?, sourceFrame: CGRect?) -> UIAlertController { let actionController = UIAlertController(title: title, message: message, preferredStyle: .actionSheet) if actionController.responds(to: #selector(getter: popoverPresentationController)) { actionController.popoverPresentationController?.sourceView = sourceView ?? StoryboardHelper.tabBarControllerTopController()?.view actionController.popoverPresentationController?.sourceRect = sourceFrame ?? CGRect(x: 0, y: 0, width: 0, height: 0) } return actionController } } 

我也面临同样的问题,最终得到了解决办法。 这是我的目标c的解决scheme

 UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"Select you option:" message:nil preferredStyle:UIAlertControllerStyleActionSheet]; UIAlertAction *action = [UIAlertAction actionWithTitle:@“share” style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) { // do other things }]; [alertController addAction:action]; UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleCancel handler:^(UIAlertAction *action) { }]; [alertController addAction:cancelAction]; // Remove arrow from action sheet. [alertController.popoverPresentationController setPermittedArrowDirections:0]; //For set action sheet to middle of view. CGRect rect = self.view.frame; rect.origin.x = self.view.frame.size.width / 20; rect.origin.y = self.view.frame.size.height / 20; alertController.popoverPresentationController.sourceView = self.view; alertController.popoverPresentationController.sourceRect = rect; [self presentViewController:alertController animated:YES completion:nil]; 

Swift 3

shareMenu.popoverPresentationController?.sourceView = self.view shareMenu.popoverPresentationController?.sourceRect = CGRect(x:view.bounds.size.width,y:view.bounds.size.height-80,width:1.0,height:1.0)

源rect是从你想显示popover视图的点。

斯威夫特4

popoverPresentationController.permittedArrowDirections = .init(rawValue: 0) popoverPresentationController.sourceView = self.view popoverPresentationController.sourceRect = CGRect(x: self.view.bounds.midX, y: self.view.bounds.midY, width: 0, height: 0)

我使用这个代码,很容易理解,也许我可以帮助任何

 //if iPhone if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone) { [self presentViewController:actionSheet animated:YES completion:nil]; } //if iPad else { // Change Rect to position Popover UIPopoverController *popup = [[UIPopoverController alloc] initWithContentViewController:actionSheet]; [popup presentPopoverFromRect:CGRectMake(self.view.frame.size.width/2, self.view.frame.size.height/4, 0, 0)inView:self.view permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES]; }