ActionSheet non funziona iPad


86

Sto usando ActionSheet nella mia applicazione. Sul mio iPhone funziona, ma non sul simulatore iPad.

questo è il mio codice:

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

E il mio errore:

Chiusura dell'app a causa di un'eccezione non rilevata "NSGenericException", motivo: "L'applicazione ha presentato un UIAlertController () di stile UIAlertControllerStyleActionSheet. Il modalPresentationStyle di un UIAlertController con questo stile è UIModalPresentationPopover. È necessario fornire le informazioni sulla posizione per questo popover tramite il popoverPresentationController del controller degli avvisi. È necessario fornire sourceView e sourceRect o barButtonItem. Se queste informazioni non sono note quando presenti il ​​controller degli avvisi, puoi fornirle nel metodo UIPopoverPresentationControllerDelegate -prepareForPopoverPresentation. '


Questo collegamento può aiutarti.
Nimisha Patel

4
ios 8 e versioni successive non è presente alcuna istanza UIActionController del foglio di azione che devi impostare il tipo come UIAlertControllerStyleActionSheet .... questo può aiutarti .... sebbene uipopover sia suggerito per iPad ....
Arun

Devi presentarlo come popover su iPad
Totka

Risposte:


110

Devi fornire una vista sorgente o un pulsante appena prima di presentare optionMenu poiché su iPad è un UIPopoverPresentationController, come dice il tuo errore. Ciò significa solo che il tuo foglio di azione punta al pulsante che consente all'utente di sapere da dove è iniziato.

Ad esempio, se stai presentando il tuo optionMenu toccando l'elemento destro della barra di navigazione. Potresti fare qualcosa del genere:

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

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

oppure puoi impostare una vista come questa: (ti serve solo una di queste 2)

optionMenu.popoverPresentationController?.sourceView = yourView

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

Tieni inoltre presente che se modifichi il tuo UIAlertControllerStyle in Alert invece del foglio di azione, non dovresti specificarlo. Sono sicuro che devi averlo capito, ma volevo solo aiutare chiunque si imbattesse in questa pagina.


31

Lo stesso problema per me. Avevo un UIAlertController che funzionava bene sul telefono, ma si bloccava su iPad. Il foglio si apre quando si tocca una cella da una vista tabella.

Per Swift 3, ho aggiunto 3 righe di codice subito prima di presentarlo:

        ...

        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
Questo ha funzionato per me in Swift 5.0 ma non so come mostrare il pop-up dalla parte inferiore della vista. Grazie!
Florentin Lupascu

@FlorentinLupascu: basta impostare allowedArrowDirections su UIPopoverArrowDirection.Down e sourceRect = CGRect (x: self.view.bounds.midX, y: self.view.bounds.bottom, width: 0, height: 0)
anche

24

Swift 3

Come detto prima, è necessario configurare UIAlertController per essere presentato in un punto specifico su iPAD.

Esempio di barra di navigazione:

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

Se desideri presentarlo al centro senza frecce [ 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)

5

aggiungere dichiarazioni nei seguenti termini prima di essere presentate.

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

funzionerà bene.


Ha funzionato perfettamente. L'unica cosa è che devi aggiungere l'elemento della barra di navigazione a sinistra, quindi il menu popover non sembra uscito dal nulla
Eugene Pavlov

0

Solo una nota che puoi anche ottenere questo errore se non hai collegato la sourceview in IB alla variabile pertinente nella tua app.


0

è necessario aggiungerlo per Ipad

alertControler.popoverPresentationController?.sourceView = self.view


Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.