Search code examples
iosipaduser-interfaceuialertcontroller

Presenting a UIAlertController properly on an iPad using iOS 8


With iOS 8.0, Apple introduced UIAlertController to replace UIActionSheet. Unfortunately, Apple didn't add any information on how to present it. I found an entry about it on hayaGeek's blog, however, it doesn't seem to work on iPad. The view is totally misplaced:

Misplaced: Misplaced image

Correct: enter image description here

I use the following code to show it on the interface:

    let alert = UIAlertController()
    // setting buttons
    self.presentModalViewController(alert, animated: true)

Is there another way to add it for iPad? Or did Apple just forget the iPad, or not implemented, yet?


Solution

  • You can present a UIAlertController from a popover by using UIPopoverPresentationController.

    In Obj-C:

    UIViewController *self; // code assumes you're in a view controller
    UIButton *button; // the button you want to show the popup sheet from
    
    UIAlertController *alertController;
    UIAlertAction *destroyAction;
    UIAlertAction *otherAction;
    
    alertController = [UIAlertController alertControllerWithTitle:nil
                                                          message:nil
                               preferredStyle:UIAlertControllerStyleActionSheet];
    destroyAction = [UIAlertAction actionWithTitle:@"Remove All Data"
                                             style:UIAlertActionStyleDestructive
                                           handler:^(UIAlertAction *action) {
                                               // do destructive stuff here
                                           }];
    otherAction = [UIAlertAction actionWithTitle:@"Blah"
                                           style:UIAlertActionStyleDefault
                                         handler:^(UIAlertAction *action) {
                                             // do something here
                                         }];
    // note: you can control the order buttons are shown, unlike UIActionSheet
    [alertController addAction:destroyAction];
    [alertController addAction:otherAction];
    [alertController setModalPresentationStyle:UIModalPresentationPopover];
    
    UIPopoverPresentationController *popPresenter = [alertController 
                                                  popoverPresentationController];
    popPresenter.sourceView = button;
    popPresenter.sourceRect = button.bounds;
    [self presentViewController:alertController animated:YES completion:nil];
    

    Editing for Swift 4.2, though there are many blogs available for the same but it may save your time to go and search for them.

    if let popoverController = yourAlert.popoverPresentationController {
        popoverController.sourceView = self.view //to set the source of your alert
        popoverController.sourceRect = CGRect(x: self.view.bounds.midX, y: self.view.bounds.midY, width: 0, height: 0) // you can set this as per your requirement.
        popoverController.permittedArrowDirections = [] //to hide the arrow of any particular direction
    }