J'ai poussé une vue sur le contrôleur de navigation et lorsque j'appuie sur le bouton de retour, elle revient automatiquement à la vue précédente. Je veux faire quelques choses lorsque le bouton de retour est enfoncé avant de faire sortir la vue de la pile. Quelle est la fonction de rappel du bouton retour?
102
Réponses:
La réponse de William Jockusch résout ce problème avec une astuce facile.
la source
À mon avis, la meilleure solution.
Mais cela ne fonctionne qu'avec iOS5 +
la source
il est probablement préférable de remplacer le bouton arrière pour pouvoir gérer l'événement avant que la vue ne s'affiche pour des choses telles que la confirmation de l'utilisateur.
dans viewDidLoad, créez un UIBarButtonItem et définissez self.navigationItem.leftBarButtonItem en lui passant un sel
Ensuite, vous pouvez faire des choses comme élever un UIAlertView pour confirmer l'action, puis afficher le contrôleur de vue, etc.
Ou au lieu de créer un nouveau bouton arrière, vous pouvez vous conformer aux méthodes de délégué UINavigationController pour effectuer des actions lorsque le bouton Précédent est enfoncé.
la source
UINavigationControllerDelegate
n'a pas de méthodes qui sont appelées lorsque le bouton retour est appuyé.C'est la bonne façon de détecter cela.
cette méthode est également appelée lorsque la vue est poussée. Donc, vérifier le parent == nil est pour faire sauter le contrôleur de vue de la pile
la source
Je me retrouve avec ces solutions. Lorsque nous tapons sur le bouton retour, la méthode viewDidDisappear est appelée. nous pouvons vérifier en appelant le sélecteur isMovingFromParentViewController qui renvoie true. nous pouvons renvoyer les données (en utilisant le délégué). J'espère que cela aidera quelqu'un.
la source
[super viewDidDisappear:animated]
C'est peut-être un peu trop tard, mais je voulais aussi le même comportement avant. Et la solution que j'ai choisie fonctionne assez bien dans l'une des applications actuellement sur l'App Store. Comme je n'ai vu personne utiliser une méthode similaire, j'aimerais la partager ici. L'inconvénient de cette solution est qu'elle nécessite un sous-classement
UINavigationController
. Bien que l'utilisation de Method Swizzling puisse aider à éviter cela, je ne suis pas allé aussi loin.Ainsi, le bouton de retour par défaut est en fait géré par
UINavigationBar
. Lorsqu'un utilisateur appuie sur le bouton de retour,UINavigationBar
demandez à son délégué s'il doit apparaître en hautUINavigationItem
en appelantnavigationBar(_:shouldPop:)
.UINavigationController
implémente réellement ceci, mais il ne déclare pas publiquement qu'il adopteUINavigationBarDelegate
(pourquoi!?). Pour intercepter cet événement, créez une sous-classe deUINavigationController
, déclarez sa conformitéUINavigationBarDelegate
et implémenteznavigationBar(_:shouldPop:)
. Renvoyeztrue
si l'élément supérieur doit être sauté. Revenezfalse
s'il doit rester.Il y a deux problèmes. La première est que vous devez appeler la
UINavigationController
version denavigationBar(_:shouldPop:)
à un moment donné. MaisUINavigationBarController
ne le déclare pas publiquement conforme àUINavigationBarDelegate
, essayer de l'appeler entraînera une erreur de compilation. La solution que j'ai choisie est d'utiliser le runtime Objective-C pour obtenir directement l'implémentation et l'appeler. Veuillez me faire savoir si quelqu'un a une meilleure solution.L'autre problème est qu'il
navigationBar(_:shouldPop:)
est appelé en premier aprèspopViewController(animated:)
si l'utilisateur appuie sur le bouton de retour. L'ordre s'inverse si le contrôleur de vue est sauté en appelantpopViewController(animated:)
. Dans ce cas, j'utilise un booléen pour détecter sipopViewController(animated:)
est appelé avant,navigationBar(_:shouldPop:)
ce qui signifie que l'utilisateur a tapé sur le bouton de retour.De plus, je crée une extension
UIViewController
pour permettre au contrôleur de navigation de demander au contrôleur de vue s'il doit être affiché si l'utilisateur appuie sur le bouton de retour. Les contrôleurs de vue peuvent revenirfalse
et effectuer toutes les actions nécessaires et appelerpopViewController(animated:)
plus tard.Et dans vous regardez les contrôleurs, implémentez
shouldBePopped(_:)
. Si vous n'implémentez pas cette méthode, le comportement par défaut sera de faire apparaître le contrôleur de vue dès que l'utilisateur appuie sur le bouton de retour comme d'habitude.Vous pouvez regarder ma démo ici .
la source
Pour "AVANT de sortir la vue de la pile":
la source
Il existe un moyen plus approprié que de demander aux viewControllers. Vous pouvez faire de votre contrôleur un délégué de la navigationBar qui a le bouton retour. Voici un exemple. Dans l'implémentation du contrôleur où vous souhaitez gérer la pression sur le bouton retour, dites-lui qu'il implémentera le protocole UINavigationBarDelegate:
Puis quelque part dans votre code d'initialisation (probablement dans viewDidLoad), faites de votre contrôleur le délégué de sa barre de navigation:
Enfin, implémentez la méthode shouldPopItem. Cette méthode est appelée dès que le bouton retour est enfoncé. Si vous avez plusieurs contrôleurs ou éléments de navigation dans la pile, vous voudrez probablement vérifier lequel de ces éléments de navigation est affiché (le paramètre d'élément), afin de ne faire vos tâches personnalisées que lorsque vous le souhaitez. Voici un exemple:
la source
Si vous ne pouvez pas utiliser "viewWillDisappear" ou une méthode similaire, essayez de sous-classer UINavigationController. Voici la classe d'en-tête:
Classe d'implémentation:
D'autre part, vous devez lier ce viewController à votre NavigationController personnalisé, donc, dans votre méthode viewDidLoad pour votre viewController régulier, procédez comme suit:
la source
Voici une autre façon que j'ai implémentée (je ne l'ai pas testé avec une séquence de déroulement mais cela ne se différencierait probablement pas, comme d'autres l'ont indiqué en ce qui concerne d'autres solutions sur cette page) pour que le contrôleur de vue parent effectue des actions avant que le VC enfant qu'il ne pousse est sorti de la pile de vues (je l'ai utilisé quelques niveaux en dessous de l'UINavigationController d'origine). Cela pourrait également être utilisé pour effectuer des actions avant que le childVC ne soit poussé. Cela a l'avantage supplémentaire de travailler avec le bouton de retour du système iOS, au lieu d'avoir à créer un UIBarButtonItem ou UIButton personnalisé.
Demandez à votre VC parent d'adopter le
UINavigationControllerDelegate
protocole et de vous inscrire aux messages des délégués:Implémentez cette
UINavigationControllerDelegate
méthode d'instance dansMyParentViewController
:Si vous spécifiez une fonction de rappel spécifique dans la
UINavigationControllerDelegate
méthode d'instance ci-dessus}
la source
Voici ce que cela fonctionne pour moi dans Swift:
la source
Si vous utilisez un Storyboard et que vous venez d'un push segue, vous pouvez également simplement remplacer
shouldPerformSegueWithIdentifier:sender:
.la source