UIAlertController is Crashed (iPad)

33,746

Solution 1

To keep it device independent, rather use it as shown in the snippet below. This code will return nil for popoverPresentationController on an iPhone / compact size device, so you can safely use it in universal projects.

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

Solution 2

try this code:

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)

Solution 3

Swift 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)

Solution 4

reference: ActionSheet Popover on iPad in Swift

create popoverController :

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

if you want show alert with indicator view should:

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

with indicator

show alert in center:

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

center no 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

Solution 5

I am also face same issue and finally got the solution. Here is my solution for 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];
Share:
33,746
Admin
Author by

Admin

Updated on July 09, 2022

Comments

  • Admin
    Admin almost 2 years

    I am using Xcode 6 to develop an iOS Application.

    When I used UIAlertController, it can be worked well on iPhone 6 simulator, but crashes on iPad simulator.

    My problem while clicking "share", then it could be crashed. How could I solve it?

    Here is my Code:

    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 showed this message:

    ******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******
    
  • deloki
    deloki over 7 years
    just had this issue on iOS10, dont think its fixed
  • Harish
    Harish over 7 years
    Actually, you don't need to perform the if let check as if the popoverPresentationController is nil nothing will be set.
  • Adam Smaka
    Adam Smaka over 7 years
    .sourceView should be sender, not self.view in order to display proper arrow direction
  • Harry Bloom
    Harry Bloom about 7 years
    yep, just popoverPresentationController?.sourceView = self.view and popoverPresentationController?.sourceRect = sender.bounds will suffice
  • SpaceTrucker
    SpaceTrucker almost 7 years
    curious why we're dividing by 20 here. I tried 2.0 and that puts it in the bottom right. Something about the geometry is unclear.
  • Ichor de Dionysos
    Ichor de Dionysos over 6 years
    What exactly is the sender in this case? Is it the view on which the action was performed?
  • Karoly Nyisztor
    Karoly Nyisztor over 6 years
    Yes, the sender is the UIControl or UIView that fired the action.
  • kurtanamo
    kurtanamo over 6 years
    Swift 4 for remove arrow: popoverPresentationController.permittedArrowDirections = .init(rawValue: 0)
  • Cerlin
    Cerlin over 6 years
    Can you explain CGRectMake(self.view.bounds.size.width / 2.0, self.view.bounds.size.height / 2.0, 1.0, 1.0)?
  • Cœur
    Cœur about 5 years
    @CerlinBoss this defines a 1 pixel square in the middle of the view as to where the menu arrow should point to.