ActionSheetがiPadで機能しない


86

アプリケーションで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'が原因でアプリを終了しています、理由: 'アプリケーションがスタイルUIAlertControllerStyleActionSheetのUIAlertController()を提示しました。このスタイルのUIAlertControllerのmodalPresentationStyleはUIModalPresentationPopoverです。アラートコントローラのpopoverPresentationControllerを介して、このポップオーバーの位置情報を提供する必要があります。sourceViewとsourceRect、またはbarButtonItemのいずれかを指定する必要があります。アラートコントローラを提示するときにこの情報がわからない場合は、UIPopoverPresentationControllerDelegateメソッド-prepareForPopoverPresentationで提供できます。


このリンクはあなたを助けるかもしれません。
Nimisha Patel 2015

4
IOS 8と何のアクションシートUIActionControllerインスタンスが存在しない以上uipopoverは、iPadのために示唆されているがuは....これはあなたを助けるかもしれない.... UIAlertControllerStyleActionSheetようなタイプを設定する必要があります....
アルン

iPadでポップオーバーとして提示する必要があります
Totka 2015年

回答:


110

エラーにあるように、iPadではUIPopoverPresentationControllerであるため、optionMenuを表示する直前にソースビューまたはボタンを指定する必要があります。これは、アクションシートがボタンを指していることを意味し、ユーザーにボタンの開始位置を知らせます。

たとえば、右側のナビゲーションバー項目をタップしてoptionMenuを表示している場合です。あなたはこのようなことをすることができます:

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

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

または、次のようなビューを設定できます:(これら2つのうちの1つが必要です)

optionMenu.popoverPresentationController?.sourceView = yourView

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

また、UIAlertControllerStyleをアクションシートではなくアラートに変更する場合は、これを指定する必要がないことにも注意してください。あなたはそれを理解したに違いないが、私はこのページに出くわした人を助けたかっただけだ。


30

私にとっても同じ問題です。電話では正常に動作する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
これはSwift5.0で機能しましたが、ビューの下からポップアップを表示する方法がわかりません。ありがとうございました!
FlorentinLupascu19年

@FlorentinLupascu:ちょうどはUIPopoverArrowDirection.DownにpermittedArrowDirectionsを設定し、sourceRect = CGRect(X:self.view.bounds.midX、Y:self.view.bounds.bottom、幅:0、高さ:0)
あまりにも

24

スウィフト3

前に述べたように、iPADの特定のポイントに表示されるようにUIAlertControllerを構成する必要があります。

ナビゲーションバーの例:

    // 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

矢印のない中央に表示したい場合[ Swift3 + ]:

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)

5

提示する前に、次の用語でステートメントを追加してください。

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 2017年

0

IBのソースビューをアプリの関連する変数にリンクしていない場合にも、このエラーが発生する可能性があることに注意してください。


0

Ipad用にこれを追加する必要があります

alertControler.popoverPresentationController?.sourceView = self.view


弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.