Estou usando o ActionSheet em meu aplicativo. No meu iPhone funciona, mas não no simulador do iPad.
este é o meu 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)
}
E meu erro:
Encerrando o aplicativo devido à exceção não detectada 'NSGenericException', motivo: 'Seu aplicativo apresentou um UIAlertController () do estilo UIAlertControllerStyleActionSheet. O modalPresentationStyle de um UIAlertController com este estilo é UIModalPresentationPopover. Você deve fornecer informações de localização para este popover por meio do popoverPresentationController do controlador de alerta. Você deve fornecer um sourceView e sourceRect ou um barButtonItem. Se esta informação não for conhecida quando você apresentar o controlador de alerta, você pode fornecê-la no método UIPopoverPresentationControllerDelegate -prepareForPopoverPresentation. '
fonte
Respostas:
Você precisa fornecer uma visualização de fonte ou botão antes de apresentar optionMenu, pois no iPad é um UIPopoverPresentationController, como diz em seu erro. Isso significa apenas que sua folha de ação aponta para o botão, permitindo ao usuário saber de onde começou.
Por exemplo, se você estiver apresentando seu optionMenu tocando no item direito da barra de navegação. Você poderia fazer algo assim:
optionMenu.popoverPresentationController?.barButtonItem = self.navigationItem.rightBarButtonItem self.presentViewController(optionMenu, animated: true, completion: nil)
ou você pode definir uma visualização como esta: (Você só precisa de um destes 2)
optionMenu.popoverPresentationController?.sourceView = yourView self.presentViewController(optionMenu, animated: true, completion: nil)
Também tenha em mente que se você alterar seu UIAlertControllerStyle para Alert em vez da planilha de ação, você não precisará especificar isso. Tenho certeza de que você deve ter percebido, mas eu só queria ajudar qualquer pessoa que encontrar esta página.
fonte
O mesmo problema para mim. Eu tinha um UIAlertController que funcionava bem no telefone, mas travou no iPad. A folha aparece quando uma célula é tocada em uma visualização de tabela.
Para o Swift 3, adicionei 3 linhas de código antes de apresentá-lo:
... 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)
fonte
Swift 3
Como dito antes, você deve configurar o UIAlertController para ser apresentado em um ponto específico no iPAD.
Exemplo de barra de navegação:
// 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") }
fonte
Se você deseja apresentá-lo no centro, sem setas [ 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)
fonte
adicione declarações nos seguintes termos antes de apresentados.
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) }
vai funcionar bem.
fonte
Apenas uma observação de que você também pode obter esse erro se não tiver vinculado a visualização da fonte em IB à variável relevante em seu aplicativo.
fonte
você precisa adicionar isso para Ipad
alertControler.popoverPresentationController?.sourceView = self.view
fonte
Eu fiz este pacote para gerenciar ActionSheet e Popover no iPhone, Ipad e Mac. https://github.com/AndreaMiotto/ActionOver
fonte