web-dev-qa-db-fra.com

ActionSheet ne fonctionne pas iPad

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 la classe UIAlertControllerStyleActionSheet. Le modalPresentationStyle d'un UIAlertController avec ce style est UIModalPresentationPopover. Vous doit fournir des informations de localisation pour ce popover par le biais de l'alerte popoverPresentationController du contrôleur. Vous devez fournir soit un sourceView et sourceRect ou un barButtonItem. Si cette information est pas connu lorsque vous présentez le contrôleur d’alertes, vous pouvez le fournir en la méthode UIPopoverPresentationControllerDelegate -prepareForPopoverPresentation. '

69
Stephany

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

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

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

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

ou vous pouvez définir une vue comme celle-ci: (vous n’avez besoin que de l’un de ces 2)

optionMenu.popoverPresentationController?.sourceView = yourView

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

N'oubliez pas non plus que si vous modifiez votre UIAlertControllerStyle en Alert au lieu d'une feuille d'action, vous n'avez pas besoin de spécifier cela. Je suis sûr que vous avez dû vous en rendre compte, mais je voulais simplement aider tous ceux qui rencontrent cette page.

99
MD Singh

Même problème pour moi. J'ai eu un UIAlertController qui a bien fonctionné sur le téléphone, mais s'est écrasé sur l'iPad. La feuille apparaît lorsqu'une cellule est exploitée à partir d'une vue sous forme 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)
22
Zach

Swift 3

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

Exemple pour la 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")
    }
21
mourodrigo

ajouter des déclarations dans les termes suivants avant présentés.

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.

4
Jimmy chou

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)
2
Mohit Singh

Notez simplement que vous pouvez également obtenir cette erreur si vous n'avez pas lié la sourceview dans IB à la variable correspondante dans votre application.

0
Peter Johnson