ActionSheet not working iPad

30,128

Solution 1

You need to provide a source view or button just before presenting optionMenu since on iPad its a UIPopoverPresentationController, As it says in your error. This just means that your action sheet points to the button letting the user know where it started from.

For example if you're presenting your optionMenu by tapping on the right navigation bar item. You could do something like this:

optionMenu.popoverPresentationController?.barButtonItem = self.navigationItem.rightBarButtonItem

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

or you could set a view like this:(You just need one of these 2)

optionMenu.popoverPresentationController?.sourceView = yourView

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

Also keep in mind that if you change your UIAlertControllerStyle to Alert instead of action sheet, You wouldn't need to specify this. I am sure you must have figured it out but i just wanted to help anyone who comes across this page.

Solution 2

Same problem for me. I had a UIAlertController that worked fine on phone, but crashed on iPad. The sheet pops up when a cell is tapped from a table view.

For Swift 3, I added 3 lines of code right before presenting it:

        ...

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


        self.present(sheet, animated: true, completion: nil)

Solution 3

Swift 3

As said before, you should configure UIAlertController to be presented on a specific point on iPAD.

Example for navigation bar:

    // 1
    let optionMenu = UIAlertController(title: nil, message: "Choose an option", preferredStyle: .actionSheet)

    // 2
    let deleteAction = UIAlertAction(title: "Option 1", style: .default, handler: {
        (alert: UIAlertAction!) -> Void in
        print("option 1 pressed")
    })
    let saveAction = UIAlertAction(title: "Option 2", style: .default, handler: {
        (alert: UIAlertAction!) -> Void in
        print("option 2 pressed")
    })

    //
    let cancelAction = UIAlertAction(title: "Cancel", style: .cancel, handler: {
        (alert: UIAlertAction!) -> Void in
        print("Cancelled")
    })


    // 4

    optionMenu.addAction(deleteAction)
    optionMenu.addAction(saveAction)
    optionMenu.addAction(cancelAction)

    // 5

    optionMenu.popoverPresentationController?.barButtonItem = self.navigationItem.rightBarButtonItem

    self.present(optionMenu, animated: true) { 
        print("option menu presented")
    }

Solution 4

If you wish to present it in the centre with no arrows [Swift 3+]:

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

Solution 5

add statements in the following terms before presented.

optionMenu.popoverPresentationController.sourceView = self.view;
optionMenu.popoverPresentationController.sourceRect = 

CGRectMake(0,0,1.0,1.0);


@IBAction func dialog(sender: AnyObject) {
    ...

    optionMenu.popoverPresentationController.sourceView = self.view;
    optionMenu.popoverPresentationController.sourceRect = CGRectMake(0,0,1.0,1.0);

    self.presentViewController(optionMenu, animated: true, completion: nil)
}

it will work well.

Share:
30,128

Related videos on Youtube

Stephany
Author by

Stephany

Updated on July 08, 2022

Comments

  • Stephany
    Stephany almost 2 years

    I'm using ActionSheet in my application. On my iPhone it works, but it doesn't on the iPad simulator.

    this is my code:

    @IBAction func dialog(sender: AnyObject) {
    
        let optionMenu = UIAlertController(title: nil, message: "Choose Option", preferredStyle: .ActionSheet)
        let deleteAction = UIAlertAction(title: "Delete", style: .Default, handler: {
    
            (alert: UIAlertAction!) -> Void in
            println("Filtre Deleted")
        })
    
        let cancelAction = UIAlertAction(title: "Cancel", style: .Cancel, handler: {
            (alert: UIAlertAction!) -> Void in
            println("Cancelled")
        })
    
        optionMenu.addAction(deleteAction)
        optionMenu.addAction(cancelAction)
    
        self.presentViewController(optionMenu, animated: true, completion: nil)
    }
    

    And my error:

    Terminating app due to uncaught exception 'NSGenericException', reason: 'Your application has presented a UIAlertController () 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 present the alert controller, you may provide it in the UIPopoverPresentationControllerDelegate method -prepareForPopoverPresentation.'

    • Nimisha Patel
      Nimisha Patel over 9 years
      This Link may help you.
    • Arun
      Arun over 9 years
      ios 8 and above there is no action sheet UIActionController instance u need to set the type as UIAlertControllerStyleActionSheet .... this may help you .... though uipopover is suggested for iPad ....
    • Totka
      Totka over 9 years
      You have to present it as a popover on iPad
  • Eugene Pavlov
    Eugene Pavlov about 7 years
    Worked perfectly. The only thing is that you need to add Left Navigation bar Item, so the popover menu doesn't look like it's coming out of nowhere
  • Florentin Lupascu
    Florentin Lupascu over 5 years
    This worked for me in Swift 5.0 but I don't know how to show the pop-up from the bottom of the view. Thank you!
  • too
    too about 5 years
    @FlorentinLupascu: Just set permittedArrowDirections to UIPopoverArrowDirection.Down and sourceRect = CGRect(x: self.view.bounds.midX, y: self.view.bounds.bottom, width: 0, height: 0)