Comportamento estranho do botão de cancelamento de UIActionSheet


116

Eu tenho um UIBarButtonItem abrindo uma folha de ação para oferecer aos usuários opções sobre o que fazer. Tudo funciona conforme o esperado, a menos que eu tente clicar no botão "Cancelar". O alvo do botão parece ter subido de onde deveria estar. Só posso ativá-lo clicando em algum lugar no meio dos botões "Cancelar" e "Ok".

Eu tentei planilhas de ação em outros aplicativos e elas funcionam bem, então não é apenas meu dedão. A folha de ação está abrindo em um UIViewController

- (void)showOpenOptions
{
    UIActionSheet *sheet = [[UIActionSheet alloc] 
    initWithTitle:NSLocalizedString(@"Open link in external application?", @"Open in external application")
    delegate:self
    cancelButtonTitle:NSLocalizedString(@"Cancel", @"Cancel")
    destructiveButtonTitle:NSLocalizedString(@"Open Link", @"Open Link")
    otherButtonTitles:nil];

    [sheet showInView:self.view];
    [sheet release];
}

5
Em uma nota não relacionada, fui informado na WWDC durante uma sessão de revisão da IU da Apple que o botão vermelho nas Folhas de Ação é realmente destinado a ações 'destrutivas' (ou seja, 'excluir').
— Ramin

Sim, eu li as diretrizes da interface humana recentemente e vi isso. Mudou de vermelho para cinza.
— nevan king

Respostas:


190

Em vez de passar a visão do controlador de visão atual para a folha de ação, use o showFromTabBar:método de UIActionSheet.

O Caminho Certo
Isso fornecerá a área tocável correta:

[actionSheet showFromTabBar:self.tabBarController.tabBar];

The Wrong Way
Isso colocará a área tocável no lugar errado (se você estiver usando uma barra de guias ou barra de ferramentas):

[actionSheet showInView:self.view];

Se você estiver usando uma barra de ferramentas , use o showFromToolbar:método. Você precisará de uma referência à barra de ferramentas, provavelmente um ivar

[actionSheet showFromToolbar:self.myToolbar];

Minha velha resposta também funciona, mas é hacky:

Acabei de encontrar uma resposta possível:

01-Dez-2008 10:22 PM Tom Saxton: Eu examinei esse bug um pouco mais, e parece ser um problema com a barra de guias.

Se você chamar UIActionSheet's [sheet showInView: self.view] de um controlador de visualização que é filho de um UITabViewController, o teste de clique no botão cancelar falha naquela parte do UIActionSheet que fica acima da visualização da barra de guias.

Se, em vez disso, você passar a visualização do UITabBarController, o UIActionSheet funcionará conforme o esperado.

NOTA: no iPhone OS 2.1 e anterior, o UIActionSheet surgiu da parte superior da barra da guia quando você passa pela visualização secundária, mas no 2.2, ela surge da parte inferior da barra da guia e, portanto, cobre a visualização da guia.

http://openradar.appspot.com/6410780

Editar: funciona corretamente quando eu mudo a visualização para a visualização da barra de guias

[sheet showInView:self.parentViewController.tabBarController.view];

Votei nisto porque funciona. Por que isso é melhor do que as outras respostas?
— bentford

1
Por que o parentViewController? Mesmo se a visualização estiver em uma visualização de navegação, tabBarController ainda deve apontar para o lugar certo. Funciona para mim sem o parentViewController em qualquer caso.
— Nathan

11
Outra resposta parece potencialmente melhor. Procure por [actionSheet showInView: [self.view window]]. Parece mais simples e genérico.
— Kevin de

Muito obrigado por postar esta resposta.
— fulvio

1
Não tenho barra de guias em meu aplicativo, mas ainda tenho esse problema. Resolvi com '[serf.view window]'. De qualquer maneira, não é um problema de barra de guias.
— Mike Keskinov

37

Eu encontrei uma resposta aqui que funciona.

usando: [filterActionSheet showInView:[self.view window]] :;

Eu tentei algumas maneiras de chegar à minha barra de guias e a forma como este aplicativo está configurado parece complicado ...


PERFEITO! Obrigado. Esta é a solução correta para mim, pois eu estava tendo esse problema com um UITableViewController que tinha uma barra de ferramentas, não uma TabBar como outras aqui.
— William Denniss

coisas boas, isso funcionou para mim! esta é definitivamente a maneira mais fácil de fazer isso!
— cgossain

2
Isso causa outro problema. ActionSheet aparece na orientação retrato quando o dispositivo está na paisagem (assim como todos os outros conteúdos).
— Mike Keskinov

22

Em vez disso, use:

[sheet showFromTabBar:theTabBar];

1
Eu corrigi isso de showInTabBar:para showFromTabBar:. Observe também que há um método 'showFromToolbar: `, dependendo de qual mobília de tela você tem na parte inferior da tela. Essa, eu acho, é uma resposta melhor do que a resposta aceita.
— Stephen Darlington

Stephen, está curioso para saber por que você acha que isso é melhor do que especificar showInView: theTabBar? De uma perspectiva de acoplamento, eu acho que showInView provavelmente seria mais ideal, caso mais tarde o tabBar seja descartado, talvez substituído por uma barra de ferramentas, por exemplo. O controlador de visão secundária em particular não deveria saber ou se importar, eu acho.
— Billy Gray

Se a barra de guias for descartada posteriormente, você terá que editar essa linha de código independentemente (a menos que talvez theTabBar seja uma referência mal nomeada a uma visão que foi passada). Portanto, não vejo como esse método é mais acoplado do que showInView: theTabBar. Eu uso showFromTabBar: também, pois parece mais seguro para mim. Não sei o que está acontecendo nos bastidores, mas imagino que showFromTabBar: tem menos probabilidade de quebrar em versões futuras do sistema operacional do que showFromView: com uma visualização de barra de guias.
— Christopher Pickslay

10

Aqui está a solução. Experimente isto:

[actionsheet showInView:[UIApplication sharedApplication].keyWindow];

5

Acho que uma combinação de três das respostas é a maneira certa de lidar com isso:

    [actionSheet showFromTabBar:self.tabBarController.tabBar];

ou seja, use showFromTabBar (é por isso que existe) e você não precisa do parentViewController como Nathan apontou (na verdade, self.parentViewController.tabBarController.tabBar retorna nulo para mim.


É claro que ele retorna nil, porque o controlador de visão pai (que é o UITabBarViewController) não está aninhado em outro UITabBarController, então sua propriedade tabBarController é nula.
— Dominik Seibold

1

FYI - teve o mesmo problema com a ação do UIDocumentInteractionController pisando na barra de guias. Usei o seguinte para corrigir.

UIViewController *parentView = [[self parentViewController] parentViewController];
[docController presentOptionsMenuFromRect: rect inView: parentView.view animated:YES];

-2

escrever código simples

 actionSheet.actionSheetStyle = UIActionSheetStyleDefault;

este trabalho bem

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.