操作面板在iPad上无法正常工作

88

我在我的应用程序中使用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)
}

并且我的错误:

因为应用程序呈现了一个样式为UIAlertControllerStyleActionSheet的UIAlertController()。 具有此样式的UIAlertController的modalPresentationStyle是UIModalPresentationPopover。 您必须通过警报控制器的popoverPresentationController提供此弹出窗口的位置信息。 您必须提供sourceView和sourceRect或barButtonItem中的任一项。 如果在呈现警报控制器时不知道此信息,则可以在UIPopoverPresentationControllerDelegate方法-prepareForPopoverPresentation中提供它。


这个链接可能会对你有所帮助。 - Nimisha Patel
4
iOS 8及以上版本中已经没有操作表(Action Sheet)UIActionController实例,您需要将类型设置为UIAlertControllerStyleActionSheet……这可能会有所帮助……虽然在iPad上建议使用UIPopover。 - Arun
你必须在iPad上以弹出窗口的形式呈现它。 - Totka
8个回答

112

由于在iPad上,optionMenu是使用UIPopoverPresentationController展示的,在展示之前你需要提供一个源视图或按钮,正如错误信息中所述。这意味着您的操作表指向按钮,让用户知道它从哪里开始。

例如,如果您通过点击右侧导航栏项来展示optionMenu,您可以像这样做:

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

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

或者你可以像这样设置视图:(您只需要其中一种)

optionMenu.popoverPresentationController?.sourceView = yourView

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

请注意,如果您将UIAlertControllerStyle更改为警报而不是操作表,则无需指定此内容。我相信您一定已经弄清楚了,但我只是想帮助那些遇到此问题的人。


34

我也遇到了同样的问题。我有一个UIAlertController,在手机上运行良好,但在iPad上崩溃。当从表视图中点击单元格时,该提示框会弹出。

对于Swift 3,我在显示它之前添加了3行代码:

        ...

        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)

1
这在Swift 5.0中对我有效,但我不知道如何从视图底部显示弹出窗口。谢谢! - Florentin Lupascu
@FlorentinLupascu:只需将 permittedArrowDirections 设置为 UIPopoverArrowDirection.Down,sourceRect = CGRect(x: self.view.bounds.midX, y: self.view.bounds.bottom, width: 0, height: 0)。 - too

24

Swift 3

如前所述,您应该配置 UIAlertController 在 iPad 上的特定位置进行呈现。

导航栏的示例:

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

8
如果您希望将其放置在中央且没有箭头[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)

6

请在下面的条款中添加语句。

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

它将运行良好。


工作得非常完美。唯一的问题是您需要添加左侧导航栏项,这样弹出菜单就不会看起来像是从无处冒出来的了。 - Eugene Pavlov

0

你需要为iPad添加以下内容:

alertControler.popoverPresentationController?.sourceView = self.view

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


0

请注意,如果您在IB中没有将sourceview链接到应用程序中的相关变量,则也可能会出现此错误。


0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接