ActionSheet ne fonctionne pas sur iPad

86

J'utilise ActionSheet dans mon application. Sur mon iPhone, cela fonctionne, mais pas sur le simulateur iPad.

c'est mon 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)
}

Et mon erreur:

Arrêt de l'application en raison d'une exception non interceptée «NSGenericException», raison: «Votre application a présenté un UIAlertController () de style UIAlertControllerStyleActionSheet. Le modalPresentationStyle d'un UIAlertController avec ce style est UIModalPresentationPopover. Vous devez fournir des informations d'emplacement pour ce popover via le popoverPresentationController du contrôleur d'alerte. Vous devez fournir un sourceView et sourceRect ou un barButtonItem. Si ces informations ne sont pas connues lorsque vous présentez le contrôleur d'alerte, vous pouvez les fournir dans la méthode UIPopoverPresentationControllerDelegate -prepareForPopoverPresentation. '

Stéphanie
la source
Ce lien peut vous aider.
Nimisha Patel
4
ios 8 et au-dessus, il n'y a pas d'instance UIActionController de feuille d'action.Vous devez définir le type comme UIAlertControllerStyleActionSheet .... cela peut vous aider .... bien que uipopover soit suggéré pour iPad ....
Arun
Vous devez le présenter en popover sur iPad
Totka

Réponses:

110

Vous devez fournir une vue ou un bouton source juste avant de présenter optionMenu car sur iPad, c'est un UIPopoverPresentationController, comme indiqué dans votre erreur. Cela signifie simplement que votre feuille d'action pointe vers le bouton indiquant à l'utilisateur d'où il a commencé.

Par exemple, si vous présentez votre optionMenu en appuyant sur l'élément droit de la barre de navigation. Vous pouvez faire quelque chose comme ceci:

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

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

ou vous pouvez définir une vue comme celle-ci: (Vous avez juste besoin de l'un de ces 2)

optionMenu.popoverPresentationController?.sourceView = yourView

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

Gardez également à l'esprit que si vous modifiez votre UIAlertControllerStyle en Alerte au lieu de la feuille d'action, vous n'aurez pas besoin de le spécifier. Je suis sûr que vous devez l'avoir compris, mais je voulais simplement aider tous ceux qui rencontrent cette page.

MD Singh
la source
30

Même problème pour moi. J'avais un UIAlertController qui fonctionnait bien sur le téléphone, mais qui s'est écrasé sur iPad. La feuille apparaît lorsqu'une cellule est tapée à partir d'une vue de tableau.

Pour Swift 3, j'ai ajouté 3 lignes de code juste avant de le présenter:

        ...

        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
la source
1
Cela a fonctionné pour moi dans Swift 5.0, mais je ne sais pas comment afficher la fenêtre contextuelle du bas de la vue. Merci!
Florentin Lupascu
@FlorentinLupascu: Il suffit de définir allowedArrowDirections sur UIPopoverArrowDirection.Down et sourceRect = CGRect (x: self.view.bounds.midX, y: self.view.bounds.bottom, width: 0, height: 0)
trop
24

Swift 3

Comme dit précédemment, vous devez configurer UIAlertController pour qu'il soit présenté sur un point spécifique sur iPAD.

Exemple de barre de navigation:

    // 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
la source
8

Si vous souhaitez le présenter au centre sans flèches [ 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
la source
5

ajouter des déclarations dans les termes suivants avant de les présenter.

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

cela fonctionnera bien.

Jimmy chou
la source
A parfaitement fonctionné. La seule chose à faire est que vous devez ajouter un élément de la barre de navigation gauche, de sorte que le menu contextuel ne semble pas sortir de nulle part
Eugene Pavlov
0

Veuillez noter que vous pouvez également obtenir cette erreur si vous n'avez pas lié la vue source dans IB à la variable appropriée dans votre application.

Peter Johnson
la source
0

vous devez ajouter ceci pour Ipad

alertControler.popoverPresentationController?.sourceView = self.view

Asad Farooq
la source