首页 文章

UIAlertController是Crashed(iPad)

提问于
浏览
25

我正在使用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******

8 回答

  • 4

    为了使设备保持独立,请使用它,如下面的代码段所示 . 此代码将在iPhone /紧凑型设备上为popoverPresentationController返回nil,因此您可以安全地在通用项目中使用它 .

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

    试试这段代码:

    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)
    
  • 0

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

  • 1

    我也面临同样的问题,最后得到了解决方案 . 这是我对Objective c的解决方案

    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];
    
  • 31

    我使用这个方便的扩展来创建永不崩溃的动作表

    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
        }
    
    }
    
  • 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];
        }
    
  • 0

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

    source rect是你要显示popover视图的点 .

  • 1

    reference: ActionSheet Popover on iPad in Swift

    创建popoverController:

    let alertController = UIAlertController(title: nil, message: "Alert message.", preferredStyle: .actionSheet)
    self.present(alertController, animated: true, completion: nil)
    

    如果你想要显示警报与指标视图应该:

    if let popoverController = alertController.popoverPresentationController {
        popoverController.barButtonItem = sender
    }
    

    with indicator

    在中心显示提醒:

    if let popoverController = alertController.popoverPresentationController {
      popoverController.sourceView = self.view
      popoverController.sourceRect = CGRect(x: self.view.bounds.midX, y: self.view.bounds.midY, width: 0, height: 0) 
    }
    

    center with indicator

    中心无指标:

    if let popoverController = alertController.popoverPresentationController {
      popoverController.sourceView = self.view
      popoverController.sourceRect = CGRect(x: self.view.bounds.midX, y: self.view.bounds.midY, width: 0, height: 0)
      popoverController.permittedArrowDirections = []
    }
    

    center no indicator

相关问题