ActionSheet 无法运行 iPad

我在我的应用程序中使用 ActionSheet,在我的 iPhone 上它可以工作,但在 iPad 模拟器上就不行了。

这是我的暗号:

@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)
}

我的错误是:

由于未捕获异常“ NSGenericException”而终止应用程序, 原因: ‘您的应用程序提供了一个 UIAlertController ()风格 模式的表示方式 此样式的 UIAlertController 是 UIModalPresentationPopover 必须通过警报提供这个弹出窗口的位置信息 控制器的 popoverPresentationController 或 barButtonItem。如果此信息是 当您呈现警报控制器时,如果不知道,您可以在 UIPopoverPresentationController 委托方法 - 准备“爆米花展示”

30606 次浏览

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.

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")
}

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.

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)

Just a note that you can also get this error if you haven't linked the sourceview in IB to the relevant variable in your app.

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)

you need to add this for Ipad

alertControler.popoverPresentationController?.sourceView = self.view

popoverController.sourceRect = CGRect(x: self.view.bounds.midX, y: self.view.bounds.midY, width: 0, height: 0)

I've done this package to manage ActionSheet and Popover in iPhone, Ipad and Mac. https://github.com/AndreaMiotto/ActionOver