181 votes

Définition de l'action pour le bouton "retour" dans le contrôleur de navigation

J'essaie d'écraser l'action par défaut du bouton retour dans un contrôleur de navigation. J'ai fourni une cible et une action sur le bouton personnalisé. Ce qui est étrange, c'est qu'en l'assignant à travers l'attribut backbutton, il n'y prête pas attention et se contente de sortir de la vue courante et de revenir à la racine :

UIBarButtonItem *backButton = [[UIBarButtonItem alloc] 
                                  initWithTitle: @"Servers" 
                                  style:UIBarButtonItemStylePlain 
                                  target:self 
                                  action:@selector(home)];
self.navigationItem.backBarButtonItem = backButton;

Dès que je l'ai mis en place par le biais du leftBarButtonItem sur le navigationItem il appelle mon action, mais le bouton ressemble alors à un simple bouton rond au lieu d'un bouton fléché vers l'arrière :

self.navigationItem.leftBarButtonItem = backButton;

Comment puis-je faire en sorte qu'il appelle mon action personnalisée avant de revenir à la vue Racine ? Existe-t-il un moyen d'écraser l'action de retour par défaut, ou existe-t-il une méthode qui est toujours appelée lorsque l'on quitte une vue ( viewDidUnload ne le fait pas) ?

0 votes

Action:@selector(home)] ; nécessite un : après le sélecteur action:@selector(home :)] ; sinon cela ne fonctionnera pas

7 votes

@PartySoft Ce n'est pas vrai à moins que la méthode ne soit déclarée avec les deux points. Il est parfaitement valide d'avoir des boutons qui appellent des sélecteurs qui ne prennent pas de paramètres.

0 votes

363voto

William Jockusch Points 9000

Essayez de placer ceci dans le contrôleur de vue où vous voulez détecter la pression :

-(void) viewWillDisappear:(BOOL)animated {
    if ([self.navigationController.viewControllers indexOfObject:self]==NSNotFound) {
       // back button was pressed.  We know this is true because self is no longer
       // in the navigation stack.  
    }
    [super viewWillDisappear:animated];
}

1 votes

Il s'agit d'une solution élégante, propre, agréable et très bien pensée.

0 votes

J'espère que ce système est à l'épreuve du temps ! fonctionne maintenant à merveille, j'ai pu supprimer la sous-classe personnalisée, qui ne faisait rien d'autre que piéger popViewControllerAnimated == n'était pas très réutilisable

0 votes

La réponse est géniale @William, je pense que tu as fait beaucoup de recherches, merci !

181voto

onegray Points 2226

J'ai mis en œuvre UIViewController-BackButtonHandler extension. Elle n'a pas besoin de sous-classer quoi que ce soit, il suffit de l'insérer dans votre projet et de surcharger navigationShouldPopOnBackButton méthode en UIViewController classe :

-(BOOL) navigationShouldPopOnBackButton {
    if(needsShowConfirmation) {
        // Show confirmation alert
        // ...
        return NO; // Ignore 'Back' button this time
    }
    return YES; // Process 'Back' button click and pop view controller
}

Télécharger un exemple d'application .

17 votes

C'est la solution la plus propre que j'ai vue, meilleure et plus simple que d'utiliser votre propre UIButton personnalisé. Je vous remercie de votre attention.

0 votes

Apple permet-il de modifier shouldPopItem ? Je pense que cette application peut être rejetée

4 votes

Les navigationBar:shouldPopItem: n'est pas une méthode privée puisqu'elle fait partie de UINavigationBarDelegate protocole.

40voto

HansPinckaers Points 1367

Contrairement à ce qu'a dit Amagrammer, c'est possible. Vous devez sous-classer votre navigationController . J'ai tout expliqué aquí (y compris un exemple de code).

0 votes

La documentation d'Apple ( developer.apple.com/iphone/library/documentation/UIKit/ ) indique que "Cette classe n'est pas destinée à être sous-classée". Je ne suis pas sûr de ce qu'ils entendent par là - ils pourraient vouloir dire "vous ne devriez normalement pas avoir besoin de faire cela", ou ils pourraient vouloir dire "nous

0 votes

T

1 votes

C

5voto

Alex Reynolds Points 45039

Il n'est pas possible de le faire directement. Il ya un couple de solutions de rechange:

  1. Créez votre propre coutume UIBarButtonItem qui valide sur le robinet et la pop si le test réussit
  2. Valider le contenu des champs du formulaire à l'aide d'un UITextField délégué de la méthode, comme -textFieldShouldReturn:, qui est appelé après l' Return ou Done bouton est pressé sur le clavier

L'inconvénient de la première option est que le pointant vers la gauche flèche de style du bouton retour ne peut pas être accessible à partir d'un personnalisé bouton de la barre. Donc, vous devez utiliser une image ou aller avec un style de bouton.

La deuxième option est agréable parce que vous obtenez le champ de texte de dos dans la méthode du délégué, de sorte que vous pouvez cibler votre logique de validation spécifique au champ de texte envoyé au délégué méthode de rappel.

5voto

psycho Points 568

Pour des raisons de threading, la solution mentionnée par @HansPinckaers ne me convenait pas, mais j'ai trouvé un moyen très simple de capturer une touche sur le bouton de retour, et je veux le noter ici au cas où cela pourrait éviter des heures de déception à quelqu'un d'autre. L'astuce est très simple : il suffit d'ajouter un UIButton transparent comme sous-vue à votre UINavigationBar, et de définir vos sélecteurs pour lui comme s'il s'agissait d'un vrai bouton ! Voici un exemple utilisant Monotouch et C#, mais la traduction en Objective-C ne devrait pas être trop difficile à trouver.

public class Test : UIViewController {
    public override void ViewDidLoad() {
        UIButton b = new UIButton(new RectangleF(0, 0, 60, 44)); //width must be adapted to label contained in button
        b.BackgroundColor = UIColor.Clear; //making the background invisible
        b.Title = string.Empty; // and no need to write anything
        b.TouchDown += delegate {
            Console.WriteLine("caught!");
            if (true) // check what you want here
                NavigationController.PopViewControllerAnimated(true); // and then we pop if we want
        };
        NavigationController.NavigationBar.AddSubview(button); // insert the button to the nav bar
    }
}

Fait amusant : à des fins de test et pour trouver de bonnes dimensions pour mon faux bouton, j'ai réglé sa couleur de fond sur le bleu... Et ça donne derrière le bouton de retour ! Quoi qu'il en soit, il attrape toujours toute touche visant le bouton d'origine.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X