Estoy usando ActionSheet en mi aplicación. En mi iPhone funciona, pero no en el simulador de iPad.
este es mi código:
@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)
}
Y mi error:
Finalizando la aplicación debido a la excepción no detectada 'NSGenericException', motivo: 'Su aplicación ha presentado un UIAlertController () de estilo UIAlertControllerStyleActionSheet. El modalPresentationStyle de un UIAlertController con este estilo es UIModalPresentationPopover. Debe proporcionar información de ubicación para este popover a través del popoverPresentationController del controlador de alerta. Debe proporcionar sourceView y sourceRect o barButtonItem. Si esta información no se conoce cuando presenta el controlador de alerta, puede proporcionarla en el método UIPopoverPresentationControllerDelegate -prepareForPopoverPresentation '.
fuente
Respuestas:
Debe proporcionar una vista de código fuente o un botón justo antes de presentar optionMenu, ya que en iPad es un UIPopoverPresentationController, como dice en su error. Esto solo significa que su hoja de acción apunta al botón que le permite al usuario saber desde dónde comenzó.
Por ejemplo, si presenta su optionMenu tocando en el elemento de la barra de navegación derecha. Podrías hacer algo como esto:
optionMenu.popoverPresentationController?.barButtonItem = self.navigationItem.rightBarButtonItem self.presentViewController(optionMenu, animated: true, completion: nil)
o puede establecer una vista como esta: (solo necesita uno de estos 2)
optionMenu.popoverPresentationController?.sourceView = yourView self.presentViewController(optionMenu, animated: true, completion: nil)
También tenga en cuenta que si cambia su UIAlertControllerStyle a Alerta en lugar de hoja de acción, no necesitaría especificar esto. Estoy seguro de que debe haberlo descubierto, pero solo quería ayudar a cualquiera que se encuentre con esta página.
fuente
El mismo problema para mí. Tenía un UIAlertController que funcionaba bien en el teléfono, pero fallaba en el iPad. La hoja aparece cuando se toca una celda desde una vista de tabla.
Para Swift 3, agregué 3 líneas de código justo antes de 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)
fuente
Swift 3
Como se dijo anteriormente, debe configurar UIAlertController para que se presente en un punto específico en iPAD.
Ejemplo de barra de navegación:
// 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") }
fuente
Si desea presentarlo en el centro sin flechas [ 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)
fuente
agregue declaraciones en los siguientes términos antes de que se presenten.
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) }
funcionará bien.
fuente
Solo tenga en cuenta que también puede obtener este error si no ha vinculado la vista de origen en IB a la variable relevante en su aplicación.
fuente
necesitas agregar esto para Ipad
alertControler.popoverPresentationController?.sourceView = self.view
fuente
He hecho este paquete para administrar ActionSheet y Popover en iPhone, Ipad y Mac. https://github.com/AndreaMiotto/ActionOver
fuente