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. '


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.


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)

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

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)

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.


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.


0

vous devez ajouter ceci pour Ipad

alertControler.popoverPresentationController?.sourceView = self.view


En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.