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];
}
nevan king
fonte
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];
nevan king
fonte
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 ...

conduzir
fonte
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];
Corey Floyd
fonte
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];
Viggnesh
fonte
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.

RawMean
fonte
É 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];
Mickey
fonte
-2

escrever código simples

 actionSheet.actionSheetStyle = UIActionSheetStyleDefault;

este trabalho bem

jayesh kavathiya
fonte