Comportement étrange du bouton d'annulation d'UIActionSheet

116

J'ai un UIBarButtonItem ouvrant une feuille d'action pour offrir aux utilisateurs des choix sur ce qu'il faut faire. Tout fonctionne comme prévu à moins que j'essaye de cliquer sur le bouton "Annuler". La cible du bouton semble s'être déplacée de l'endroit où elle devrait être. Je ne peux l'activer qu'en cliquant quelque part au milieu des boutons "Annuler" et "Ok".

J'ai essayé des feuilles d'action dans d'autres applications et elles fonctionnent bien, donc ce n'est pas seulement mon gros pouce. La feuille d'action s'ouvre dans un 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];
}
roi nevan
la source
5
Sur une note sans rapport, on m'a dit à la WWDC lors d'une session de révision de l'interface utilisateur Apple que le bouton rouge sur les feuilles d'action était vraiment destiné aux actions «destructrices» (c'est-à-dire «supprimer»).
Ramin
Ouais, j'ai lu les directives d'interface humaine récemment et je l'ai vu. Je l'ai changé du rouge au gris.
nevan king

Réponses:

190

Au lieu de transmettre la vue du contrôleur de vue actuel à la feuille d'actions, utilisez la showFromTabBar:méthode de UIActionSheet.

La bonne manière
Cela donnera la bonne zone de frappe:

[actionSheet showFromTabBar:self.tabBarController.tabBar];

La mauvaise manière
Cela placera la zone de frappe au mauvais endroit (si vous utilisez une barre d'onglets ou une barre d'outils):

[actionSheet showInView:self.view];

Si vous utilisez une barre d'outils , utilisez showFromToolbar:plutôt la méthode. Vous aurez besoin d'une référence à la barre d'outils, probablement un ivar

[actionSheet showFromToolbar:self.myToolbar];

Ma vieille réponse fonctionne également, mais est piratée:

Je viens de trouver une réponse possible:

01-Dec-2008 22:22 Tom Saxton: J'ai examiné ce bogue un peu plus, et cela semble être un problème avec la barre d'onglets.

Si vous appelez la [feuille showInView: self.view] de UIActionSheet à partir d'un contrôleur de vue qui est un enfant d'un UITabViewController, le test d'accès sur le bouton d'annulation échoue dans cette partie de la feuille UIActionSheet qui se trouve au-dessus de la vue de la barre d'onglets.

Si vous passez à la place dans la vue UITabBarController, l'UIActionSheet agit comme prévu.

REMARQUE: dans iPhone OS 2.1 et versions antérieures, la feuille UIActionSheet est venue du haut de la barre d'onglets lorsque vous passez la vue enfant, mais dans la version 2.2, elle vient du bas de la barre d'onglets, et couvre ainsi la vue des onglets.

http://openradar.appspot.com/6410780

Modifier: cela fonctionne correctement lorsque je change la vue en vue de la barre d'onglets

[sheet showInView:self.parentViewController.tabBarController.view];
roi nevan
la source
J'ai voté pour cela parce que cela fonctionne. Pourquoi est-ce mieux que les autres réponses?
bentford
1
Pourquoi le parentViewController? Même si la vue se trouve dans une vue de navigation, tabBarController doit toujours pointer vers le bon endroit. Fonctionne pour moi sans le parentViewController dans tous les cas.
Nathan
11
Une autre réponse semble potentiellement meilleure. Recherchez [actionSheet showInView: [self.view window]]. Cela semble plus simple et plus générique.
Kevin
Merci beaucoup d'avoir publié cette réponse.
fulvio
1
Je n'ai pas de barre d'onglets dans mon application, mais j'ai toujours ce problème. Je l'ai résolu avec «[serf.view window]». Ce n'est pas un problème de barre d'onglets de toute façon.
Mike Keskinov
37

J'ai trouvé une réponse ici qui fonctionne.

en utilisant [filterActionSheet showInView:[self.view window]]:;

J'ai essayé plusieurs façons d'accéder à ma barre d'onglets et la façon dont cette application est configurée semble alambiquée ...

driveguy
la source
PARFAIT! Merci. C'est la solution correcte pour moi, car j'avais ce problème avec un UITableViewController qui avait une barre d'outils pas une TabBar comme d'autres ici.
William Denniss
bonnes choses, cela a fonctionné pour moi! c'est certainement le moyen le plus simple de le faire!
cgossain
2
Cela pose un autre problème. ActionSheet apparaît en orientation portrait lorsque l'appareil est en paysage (ainsi que tous les autres contenus).
Mike Keskinov
22

Utilisez plutôt:

[sheet showFromTabBar:theTabBar];
Corey Floyd
la source
1
J'ai corrigé cela de showInTabBar:à showFromTabBar:. Notez également qu'il existe une méthode 'showFromToolbar:', en fonction du mobilier d'écran que vous avez en bas de l'écran. C'est, je pense, une meilleure réponse que la réponse acceptée.
Stephen Darlington
Stephen, curieux de savoir pourquoi vous pensez que c'est mieux que de spécifier showInView: theTabBar? Du point de vue du couplage, je pense que showInView serait probablement plus idéal, au cas où plus tard le tabBar serait supprimé, peut-être remplacé par une barre d'outils, par exemple. Le contrôleur de sous-vue particulier ne devrait pas vraiment avoir à savoir ou à s'en soucier, je pense.
Billy Gray
Si la barre d'onglets est supprimée plus tard, vous allez devoir modifier cette ligne de code malgré tout (à moins que peut-être theTabBar soit une référence mal nommée à une vue transmise). Donc je ne vois pas comment cette méthode est plus couplée que showInView: theTabBar. J'utilise showFromTabBar: aussi, car cela me semble plus sûr. Je ne sais pas ce qui se passe sous les couvertures, mais j'imagine que showFromTabBar: est moins susceptible de se casser dans les futures versions du système d'exploitation que showFromView: avec une vue en barre d'onglets.
Christopher Pickslay
10

Voici le correctif, essayez ceci:

[actionsheet showInView:[UIApplication sharedApplication].keyWindow];
Viggnesh
la source
5

Je pense qu'une combinaison de trois des réponses est la bonne façon de gérer cela:

    [actionSheet showFromTabBar:self.tabBarController.tabBar];

c'est-à-dire, utilisez showFromTabBar (c'est pourquoi il existe) et vous n'avez pas besoin du parentViewController comme l'a souligné Nathan (en fait, self.parentViewController.tabBarController.tabBar renvoie nil pour moi.

RawMean
la source
Bien sûr, il renvoie nil, car le contrôleur de vue parent (qui est le UITabBarViewController) n'est pas lui-même imbriqué dans un autre UITabBarController, donc sa propriété tabBarController est nil.
Dominik Seibold
1

FYI - a eu le même problème avec la feuille d'actions de UIDocumentInteractionController pas à pas sur la barre d'onglets. Utilisé ce qui suit pour corriger.

UIViewController *parentView = [[self parentViewController] parentViewController];
[docController presentOptionsMenuFromRect: rect inView: parentView.view animated:YES];
Mickey
la source
-2

écrire du code simplifié

 actionSheet.actionSheetStyle = UIActionSheetStyleDefault;

ça marche bien

Jayesh Kavathiya
la source