Essayer de gérer le retour des boutons de navigation dans iOS

Je dois détecter le moment où l’utilisateur appuie sur le bouton “retour” de la barre de navigation, afin d’effectuer certaines opérations lorsque cela se produit. J’essaie de définir manuellement une action sur un tel bouton, de cette façon:

[self.navigationItem.backBarButtonItem setAction:@selector(performBackNavigation:)]; - (void)performBackNavigation:(id)sender { // Do operations [self.navigationController popViewControllerAnimated:NO]; } 

J’ai d’abord placé ce code dans le contrôleur de vue lui-même, mais j’ai constaté que self.navigationItem.backBarButtonItem semblait être nil , j’ai donc déplacé ce même code dans le contrôleur de vue parent, ce qui pousse le premier dans la stack de navigation. Mais je ne peux ni le faire fonctionner. J’ai lu certains articles concernant ce problème, et certains d’entre eux ont dit que le sélecteur devait être défini sur le contrôleur de la vue parente, mais pour moi, cela ne fonctionne pas du tout … Que pourrais-je faire de mal?

Merci

Essayez ce code en utilisant la méthode VIewWillDisappear pour détecter la pression du bouton Retour de NavigationItem:

 -(void) viewWillDisappear:(BOOL)animated { if ([self.navigationController.viewControllers indexOfObject:self]==NSNotFound) { // Navigation button was pressed. Do some stuff [self.navigationController popViewControllerAnimated:NO]; } [super viewWillDisappear:animated]; } 

OU Il y a une autre façon d’obtenir l’action du bouton Navigation BAck.

Créer un bouton personnalisé pour UINavigationItem du bouton retour.

Pour ex:

Dans ViewDidLoad:

 - (void)viewDidLoad { [super viewDidLoad]; UIBarButtonItem *newBackButton = [[UIBarButtonItem alloc] initWithTitle:@"Home" style:UIBarButtonItemStyleBordered target:self action:@selector(home:)]; self.navigationItem.leftBarButtonItem=newBackButton; } -(void)home:(UIBarButtonItem *)sender { [self.navigationController popToRootViewControllerAnimated:YES]; } 

Rapide :

 override func willMoveToParentViewController(parent: UIViewController?) { if parent == nil { // Back btn Event handler } } 

Rapide

 override func didMoveToParentViewController(parent: UIViewController?) { if parent == nil { //"Back pressed" } } 

Peut-être que cette réponse ne correspond pas à votre explication, mais au titre de la question. C’est utile lorsque vous essayez de savoir quand vous avez appuyé sur le bouton UINavigationBar un UINavigationBar .

Dans ce cas, vous pouvez utiliser le protocole UINavigationBarDelegate et implémenter l’une de ces méthodes:

 - (BOOL)navigationBar:(UINavigationBar *)navigationBar shouldPopItem:(UINavigationItem *)item; - (void)navigationBar:(UINavigationBar *)navigationBar didPopItem:(UINavigationItem *)item; 

Lorsque la méthode didPopItem est appelée, c’est parce que vous avez appuyé sur le bouton Retour ou que vous avez utilisé la [UINavigationBar popNavigationItemAnimated:] et que la barre de navigation a fait apparaître l’élément.

Maintenant, si vous voulez savoir quelle action a déclenché la méthode didPopItem , vous pouvez utiliser un indicateur.

Avec cette approche, je n’ai pas besoin d’append manuellement un élément de bouton de la barre de gauche avec une image en flèche afin de le rendre similaire au bouton de retour iOS et de pouvoir définir ma cible / action personnalisée.


Voyons un exemple:

J’ai un contrôleur de vue qui a un contrôleur de vue de page et une vue d’indicateur de page personnalisée. J’utilise également un UINavigationBar personnalisé pour afficher un titre afin de savoir sur quelle page je suis et le bouton Précédent pour revenir à la page précédente. Et je peux également glisser à la page précédente / suivante sur le contrôleur de page.

 #pragma mark - UIPageViewController Delegate Methods - (void)pageViewController:(UIPageViewController *)pageViewController didFinishAnimating:(BOOL)finished previousViewControllers:(NSArray *)previousViewControllers transitionCompleted:(BOOL)completed { if( completed ) { //... if( currentIndex > lastIndex ) { UINavigationItem *navigationItem = [[UINavigationItem alloc] initWithTitle:@"Some page title"]; [[_someViewController navigationBar] pushNavigationItem:navigationItem animated:YES]; [[_someViewController pageControl] setCurrentPage:currentIndex]; } else { _autoPop = YES; //We pop the item automatically from code. [[_someViewController navigationBar] popNavigationItemAnimated:YES]; [[_someViewController pageControl] setCurrentPage:currentIndex]; } } } 

Donc, j’implémente les méthodes de délégué UINavigationBar:

 #pragma mark - UINavigationBar Delegate Methods - (BOOL)navigationBar:(UINavigationBar *)navigationBar shouldPopItem:(UINavigationItem *)item { if( !_autoPop ) { //Pop by back button tap } else { //Pop from code } _autoPop = NO; return YES; } 

Dans ce cas, j’ai utilisé shouldPopItem car la pop est animée et je voulais gérer le bouton Retour immédiatement et ne pas attendre la fin de la transition.

Le problème avec didMoveToParentViewController , c’est qu’il est appelé une fois que la vue parente est à nouveau visible, donc si vous devez effectuer certaines tâches avant cela, cela ne fonctionnera pas.

Et cela ne fonctionne pas avec le geste d’animation piloté. Utiliser willMoveToParentViewController fonctionne mieux.

Objectif c

 - (void)willMoveToParentViewController:(UIViewController *)parent{ if (parent == NULL) { // ... } } 

Rapide

 override func willMoveToParentViewController(parent: UIViewController?) { if parent == nil { // ... } } 

Ceci est la version Objective-C de la réponse de dadachi :

Objectif c

 - (void)didMoveToParentViewController:(UIViewController *)parent{ if (parent == NULL) { NSLog(@"Back Pressed"); } } 

Définissez le délégué de UINavigationBar, puis utilisez:

 - (BOOL)navigationBar:(UINavigationBar *)navigationBar shouldPopItem:(UINavigationItem *)item { //handle the action here } 

Définissez UINavigationControllerDelegate et implémentez ce délégué func (Swift):

 func navigationController(navigationController: UINavigationController, willShowViewController viewController: UIViewController, animated: Bool) { if viewController is  { //if the only way to get back - back button was pressed } }