Question

J'ai besoin de savoir quand mon contrôleur de vue est sur le point de sortir d'une pile de nav afin de pouvoir exécuter une action.

Je ne peux pas utiliser -viewWillDisappear, car cette option est appelée lorsque le contrôleur de vue est déconnecté de l'écran pour TOUTE raison (comme si un nouveau contrôleur de vue était placé en haut).

J'ai particulièrement besoin de savoir quand le contrôleur est sur le point de se faire apparaître.

Toutes les idées seraient géniales, merci d'avance.

Était-ce utile?

La solution

Je ne pense pas qu'il y ait un message explicite à ce sujet, mais vous pouvez sous-classer UINavigationController et override - popViewControllerAnimated (bien que je ne l'aie jamais essayé auparavant).

Sinon, s'il n'y a pas d'autres références au contrôleur de vue, pouvez-vous ajouter à its-dealloc?

Autres conseils

Remplacez la méthode viewWillDisappear dans le VC présenté, puis cochez la case isMovingFromParentViewController dans la substitution et exécutez une logique spécifique. Dans mon cas, je cache la barre d’outils des contrôleurs de navigation. Il faut encore que votre VC présenté comprenne qu'il a été poussé mais pas parfait.

Essayez de remplacer willMoveToParentViewController: (au lieu de viewWillDisappear: ) dans votre sous-classe personnalisée de UIViewController . >

  

Appelé juste avant l'ajout ou la suppression du contrôleur de vue d'un contrôleur de vue de conteneur.

- (void)willMoveToParentViewController:(UIViewController *)parent
{
    [super willMoveToParentViewController:parent];
    if (!parent) {
        // `self` is about to get popped.
    }
}

Heureusement, au moment où la méthode viewWillDisappear est appelée, le viewController a déjà été supprimé de la pile. Nous savons donc que le viewController éclate car il ne figure plus dans le self.navigationController.viewControllers

Swift 4

override func viewWillDisappear(_ animated: Bool) {
    super.viewWillDisappear(animated)

    if let nav = self.navigationController {
        let isPopping = !nav.viewControllers.contains(self)
        if isPopping {
            // popping off nav
        } else {
            // on nav, not popping off (pushing past, being presented over, etc.)
        }
    } else {
        // not on nav at all
    }
}

Code d'origine

- (void)viewWillDisappear:(BOOL)animated {
    [super viewWillDisappear:animated];
    if ((self.navigationController) && 
        (![self.navigationController.viewControllers containsObject:self])) {
        NSLog(@"I've been popped!");
    }
}

Cela fonctionne pour moi.

- (void)viewDidDisappear:(BOOL)animated
{
    if (self.parentViewController == nil) {
        NSLog(@"viewDidDisappear doesn't have parent so it's been popped");
        //release stuff here
    } else {
        NSLog(@"PersonViewController view just hidden");
    }
}

Vous pouvez l'attraper ici.

- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated {

    if (viewController == YourAboutToAppearController) {
            // do something
    }
}

Ceci se déclenchera juste avant l'affichage de la nouvelle vue. Personne n'a encore bougé. J'utilise tout le temps pour faire de la magie devant le contrôleur de navigation asinin. Vous pouvez définir des titres et des titres de boutons et faire ce que vous voulez.

J'ai le même problème. J'ai essayé avec viewDisDisappear, mais je n'ai pas la fonction qui s'appelle :( (je ne sais pas pourquoi, peut-être parce que tout mon VC est UITableViewController). La suggestion d'Alex fonctionne bien, mais elle échoue si votre contrôleur de navigation est affiché sous l'onglet Plus. Dans ce cas, tous les VC de vos contrôleurs de navigation utilisent le navigationController comme UIMoreNavigationController, et non le contrôleur de navigation que vous avez sous-classé. Par conséquent, vous ne serez pas averti par la navigation lorsqu'un VC est sur le point de s'afficher.
Enfin, j'ai résolu le problème avec une catégorie de UINavigationController, il suffit de réécrire - (UIViewController *) popViewControllerAnimated: (BOOL) animé

- (UIViewController *)popViewControllerAnimated:(BOOL)animated{
   NSLog(@"UINavigationController(Magic)");
   UIViewController *vc = self.topViewController;
   if ([vc respondsToSelector:@selector(viewControllerWillBePopped)]) {
      [vc performSelector:@selector(viewControllerWillBePopped)];
   }
   NSArray *vcs = self.viewControllers;
   UIViewController *vcc = [vcs objectAtIndex:[vcs count] - 2];
   [self popToViewController:vcc animated:YES];
   return vcc;}

Cela fonctionne bien pour moi: D

J'ai essayé ceci:

- (void) viewWillDisappear:(BOOL)animated {
    // If we are disappearing because we were removed from navigation stack
    if (self.navigationController == nil) {
        // YOUR CODE HERE
    }

    [super viewWillDisappear:animated];
}

L'idée est qu'à navigation, le contrôleur de navigation du contrôleur de vue est défini sur nil. Donc, si la vue devait disparaître et si elle disposait plus d'un navigateurContrôleur, j'ai conclu qu'elle était apparue. (pourrait ne pas fonctionner dans d'autres scénarios).

Je ne peux pas garantir que viewWillDisappear sera appelé lors du popping, car cela n’est pas mentionné dans la documentation. J'ai essayé lorsque la vue était en vue de dessus et en dessous, et cela fonctionnait dans les deux cas.

bonne chance, Oded.

Vous pouvez utiliser celui-ci:

if(self.isMovingToParentViewController)
{
    NSLog(@"Pushed");
}
else
{
    NSLog(@"Popped");
}

Sous-classe UINavigationController et remplacement de popViewController :

Swift 3

protocol CanPreventPopProtocol {
    func shouldBePopped() -> Bool
}

class MyNavigationController: UINavigationController {
    override func popViewController(animated: Bool) -> UIViewController? {
        let viewController = self.topViewController

        if let canPreventPop = viewController as? CanPreventPopProtocol {
            if !canPreventPop.shouldBePopped() {
                return nil
            }
        }
        return super.popViewController(animated: animated)
    }

    //important to prevent UI thread from freezing
    //
    //if popViewController is called by gesture recognizer and prevented by returning nil
    //UI will freeze after calling super.popViewController
    //so that, in order to solve the problem we should not return nil from popViewController
    //we interrupt the call made by gesture recognizer to popViewController through
    //returning false on gestureRecognizerShouldBegin
    //
    //tested on iOS 9.3.2 not others
    func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
        let viewController = self.topViewController

        if let canPreventPop = viewController as? CanPreventPopProtocol {
            if !canPreventPop.shouldBePopped() {
                return false
            }
        }

        return true
    }

}

Vous pourriez peut-être utiliser la méthode de protocole de navigationBar: shouldPopItem de UINavigationBarDelegate.

Essayez de faire cette vérification dans viewwilldisappear if ([self.navigationController.viewControllers indexOfObject: self] == NSNotFound) { // le popping de cette vue est arrivé. }

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top