ActionSheet funktioniert nicht iPad

86

Ich verwende ActionSheet in meiner Anwendung. Auf meinem iPhone funktioniert es, auf dem iPad-Simulator jedoch nicht.

Das ist mein 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)
}

Und mein Fehler:

Beenden der App aufgrund der nicht erfassten Ausnahme 'NSGenericException', Grund: 'Ihre Anwendung hat einen UIAlertController () im Stil UIAlertControllerStyleActionSheet präsentiert. Der modalPresentationStyle eines UIAlertControllers mit diesem Stil ist UIModalPresentationPopover. Sie müssen Standortinformationen für dieses Popover über den popoverPresentationController des Alert-Controllers bereitstellen. Sie müssen entweder ein sourceView und sourceRect oder ein barButtonItem angeben. Wenn diese Informationen bei der Präsentation des Alert-Controllers nicht bekannt sind, können Sie sie in der UIPopoverPresentationControllerDelegate-Methode -prepareForPopoverPresentation bereitstellen. '

Stephany
quelle
Dieser Link kann Ihnen helfen.
Nimisha Patel
4
ios 8 und höher gibt es kein Aktionsblatt UIActionController-Instanz Sie müssen den Typ als UIAlertControllerStyleActionSheet festlegen .... dies kann Ihnen helfen .... obwohl uipopover für iPad empfohlen wird ....
Arun
Sie müssen es als Popover auf dem iPad präsentieren
Totka

Antworten:

110

Sie müssen eine Quellansicht oder eine Schaltfläche bereitstellen, bevor Sie optionMenu anzeigen, da es sich auf dem iPad um einen UIPopoverPresentationController handelt, wie in Ihrem Fehler angegeben. Dies bedeutet nur, dass Ihr Aktionsblatt auf die Schaltfläche zeigt, die den Benutzer darüber informiert, wo es begonnen hat.

Zum Beispiel, wenn Sie Ihr Optionsmenü präsentieren, indem Sie auf das rechte Navigationsleistenelement tippen. Sie könnten so etwas tun:

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

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

oder Sie können eine Ansicht wie folgt festlegen: (Sie benötigen nur eine dieser 2)

optionMenu.popoverPresentationController?.sourceView = yourView

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

Beachten Sie auch, dass Sie dies nicht angeben müssen, wenn Sie Ihren UIAlertControllerStyle in Alert anstelle von Action Sheet ändern. Ich bin sicher, Sie müssen es herausgefunden haben, aber ich wollte nur jedem helfen, der auf diese Seite stößt.

MD Singh
quelle
29

Gleiches Problem für mich. Ich hatte einen UIAlertController, der auf dem Telefon gut funktionierte, aber auf dem iPad abstürzte. Das Blatt wird angezeigt, wenn eine Zelle in einer Tabellenansicht angetippt wird.

Für Swift 3 habe ich 3 Codezeilen hinzugefügt, bevor ich es präsentierte:

        ...

        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)
Zach
quelle
1
Dies hat in Swift 5.0 für mich funktioniert, aber ich weiß nicht, wie ich das Popup am unteren Rand der Ansicht anzeigen soll. Danke dir!
Florentin Lupascu
@FlorentinLupascu: Setzen Sie einfach allowArrowDirections auf UIPopoverArrowDirection.Down und sourceRect = CGRect (x: self.view.bounds.midX, y: self.view.bounds.bottom, width: 0, height: 0)
auch
24

Swift 3

Wie bereits erwähnt, sollten Sie UIAlertController so konfigurieren, dass es an einem bestimmten Punkt auf dem iPAD angezeigt wird.

Beispiel für die Navigationsleiste:

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

Wenn Sie es in der Mitte ohne Pfeile präsentieren möchten [ 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)
Mohit Singh
quelle
4

Fügen Sie Aussagen in den folgenden Begriffen hinzu, bevor Sie sie präsentieren.

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

es wird gut funktionieren.

Jimmy Chou
quelle
Hat perfekt funktioniert. Das einzige ist, dass Sie das Element der linken Navigationsleiste hinzufügen müssen, damit das Popover-Menü nicht so aussieht, als käme es aus dem Nichts
Eugene Pavlov,
0

Nur ein Hinweis, dass Sie diesen Fehler auch erhalten können, wenn Sie die Quellansicht in IB nicht mit der relevanten Variablen in Ihrer App verknüpft haben.

Peter Johnson
quelle
0

Sie müssen dies für Ipad hinzufügen

alertControler.popoverPresentationController?.sourceView = self.view

Asad Farooq
quelle