136 votes

viewWillDisappear : Détermine si le contrôleur de vue est en train de disparaître ou s'il affiche un contrôleur de vue secondaire.

J'ai du mal à trouver une bonne solution à ce problème. Dans un contrôleur de vue -viewWillDisappear: je dois trouver un moyen de déterminer si c'est parce qu'un contrôleur de vue est poussé sur la pile du contrôleur de navigation, ou si c'est parce que le contrôleur de vue disparaît parce qu'il a été retiré.

Pour l'instant, je mets des drapeaux tels que isShowingChildViewController mais cela devient assez compliqué. La seule façon dont je pense pouvoir le détecter est dans le fichier -dealloc méthode.

231voto

Sbrocket Points 5267

Vous pouvez utiliser les éléments suivants.

- (void)viewWillDisappear:(BOOL)animated {
  [super viewWillDisappear:animated];
  NSArray *viewControllers = self.navigationController.viewControllers;
  if (viewControllers.count > 1 && [viewControllers objectAtIndex:viewControllers.count-2] == self) {
    // View is disappearing because a new view controller was pushed onto the stack
    NSLog(@"New view controller was pushed");
  } else if ([viewControllers indexOfObject:self] == NSNotFound) {
    // View is disappearing because it was popped from the stack
    NSLog(@"View controller was popped");
  }
}

Cela est bien sûr possible parce que la pile de contrôleurs de vue de UINavigationController (exposée à travers la propriété viewControllers) a été mise à jour au moment où viewWillDisappear est appelé.

2 votes

Parfait ! Je ne sais pas pourquoi je n'y ai pas pensé ! Je suppose que je n'ai pas pensé que la pile serait modifiée jusqu'à ce que les méthodes de disparition aient été appelées ! Merci :-)

1 votes

Je viens d'essayer de faire la même chose mais en viewWillAppear et il semblerait que le tableau viewControllers soit le même dans les deux cas, que le contrôleur de vue soit révélé en étant poussé ou que quelque chose au-dessus de lui soit sorti ! Des idées ?

0 votes

Je dois également noter que le contrôleur de vue est persistant pendant toute la durée de vie de l'application, de sorte que je ne peux pas effectuer mes actions sur les éléments suivants viewDidLoad car il n'est appelé qu'une seule fois ! Hmm, c'est une question délicate !

138voto

hacker2007 Points 952

Je pense que la méthode la plus simple est la suivante :

 - (void)viewWillDisappear:(BOOL)animated
{
    if ([self isMovingFromParentViewController])
    {
        NSLog(@"View controller was popped");
    }
    else
    {
        NSLog(@"New view controller was pushed");
    }
    [super viewWillDisappear:animated];
}

Swift :

override func viewWillDisappear(animated: Bool)
{
    if isMovingFromParent
    {
        print("View controller was popped")
    }
    else
    {
        print("New view controller was pushed")
    }
    super.viewWillDisappear(animated)
}

0 votes

Depuis iOS 5, c'est la réponse, mais vous pouvez aussi vérifier isBeingDismissed.

4 votes

Pour iOS7, je dois vérifier que [self.navigationController.viewControllers indexOfObject:self] == NSNotFound à nouveau car la mise en arrière-plan de l'application passera également ce test mais ne supprimera pas self de la pile de navigation.

3 votes

Apple a fourni une méthode documentée pour effectuer cette opération - stackoverflow.com/a/33478133/385708

18voto

dk. Points 862

Si vous voulez simplement savoir si votre vue est en train d'être captée, je viens de découvrir que self.navigationController es nil en viewDidDisappear lorsqu'il est retiré de la pile des contrôleurs. Il s'agit donc d'un test alternatif simple.

(Je découvre cela après avoir essayé toutes sortes d'autres contorsions. Je suis surpris qu'il n'y ait pas de protocole de contrôleur de navigation pour enregistrer un contrôleur de vue afin d'être notifié sur les pops. Vous ne pouvez pas utiliser UINavigationControllerDelegate car il s'agit d'un véritable travail d'affichage.)

0voto

darkfader Points 19

@pr1001 ou ceci : } else if (!self.isBeingPresented) { . Dans mon cas, j'ai un contrôleur de navigation popup. De plus, il ne serait pas inutile d'appeler la superclasse.

0voto

Byte Points 1812

Il s'agit de iOS7 Il n'est pas possible de savoir si cela s'applique à d'autres. D'après ce que je sais, en viewDidDisappear l'affichage a déjà été supprimé. Ce qui signifie que lorsque vous interrogez self.navigationController.viewControllers vous obtiendrez un nil . Il suffit donc de vérifier si elle est nulle.

TL;DR

 - (void)viewDidDisappear:(BOOL)animated
 {
    [super viewDidDisappear:animated];
    if (self.navigationController.viewControllers == nil) {
        // It has been popped!
        NSLog(@"Popped and Gone");
    }
 }

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