ActionSheet não funciona no iPad

86

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

Stephany
fonte
Este link pode ajudá-lo.
Nimisha Patel
4
ios 8 e superior não há nenhuma folha de ação instância UIActionController u precisa definir o tipo como UIAlertControllerStyleActionSheet .... isso pode ajudá-lo .... embora uipopover seja sugerido para iPad ....
Arun
Você deve apresentá-lo como um popover no iPad
Totka

Respostas:

110

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.

MD Singh
fonte
30

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)
Zach
fonte
1
Isso funcionou para mim no Swift 5.0, mas não sei como mostrar o pop-up na parte inferior da visualização. Obrigado!
Florentin Lupascu
@FlorentinLupascu: basta definir allowedArrowDirections para UIPopoverArrowDirection.Down e sourceRect = CGRect (x: self.view.bounds.midX, y: self.view.bounds.bottom, largura: 0, altura: 0)
também
24

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")
    }
mourodrigo
fonte
8

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)
Mohit Singh
fonte
5

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.

Jimmy chou
fonte
Funcionou perfeitamente. A única coisa é que você precisa adicionar o item da barra de navegação esquerda, para que o menu popover não pareça que está saindo do nada
Eugene Pavlov
0

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.

Peter Johnson
fonte
0

você precisa adicionar isso para Ipad

alertControler.popoverPresentationController?.sourceView = self.view

Asad Farooq
fonte