Pergunta

Eu preciso saber quando o meu controlador de vista está prestes a ser estalado a partir de uma pilha de nav para que eu possa executar uma ação.

Eu não posso usar -viewWillDisappear, porque que é chamada quando o controlador de vista é movido fora da tela por qualquer motivo (como um novo controlador de vista sendo empurrado em cima).

I especificamente precisa saber quando o controlador está prestes a ser exibido em si.

Todas as idéias seria fantástico, obrigado antecipadamente.

Foi útil?

Solução

Eu não acho que existe uma mensagem explícita para isso, mas você poderia subclasse o UINavigationController e substituição -. PopViewControllerAnimated (embora eu não tentei isso antes de eu)

Como alternativa, se não há outras referências para o controlador de vista, você poderia adicionar à sua -? Dealloc

Outras dicas

Substitua o método viewWillDisappear no VC apresentado, em seguida, verifique a bandeira isMovingFromParentViewController dentro do override e fazer lógica específica. No meu caso eu estou escondendo a barra de ferramentas controladores de navegação. Ainda requer que o apresentado VC entender que ele foi empurrado embora assim não perfeito.

Tente substituir willMoveToParentViewController: (em vez de viewWillDisappear:) na sua subclasse personalizada de UIViewController.

Chamado pouco antes do controlador de vista é adicionado ou removido de um controlador de vista recipiente.

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

Felizmente, no momento em que o método viewWillDisappear é chamado, o viewController já foi removido da pilha, por isso sabemos o viewController está aparecendo porque ele não está mais no self.navigationController.viewControllers <é / p>

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
    }
}

Código Original

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

Esse é um trabalho para mim.

- (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");
    }
}

Você pode pegá-lo aqui.

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

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

Isto irá disparar um pouco antes da exibição do novo View. Ninguém ainda se movia. Eu uso o tempo todo para fazer mágica na frente do NavigationController asinino. Você pode definir títulos e títulos de botão e fazer o que lá.

Eu tenho o mesmo problema. Eu tentei com viewDisDisappear, mas eu não tenho a função de obter chamado :( (não sei porquê, talvez porque toda a minha VC é UITableViewController). A sugestão de Alex funciona bem, mas ele falhar se o controlador de navegação é exibido sob a guia Mais. Neste caso, todos os VCs de seus controladores nav têm a navigationController como UIMoreNavigationController, não o controlador de navegação de ter uma subclasse, então você não será notificado pela nav quando um VC está prestes a estourou.
Finalmente, eu resolvi o problema com uma categoria de UINavigationController, apenas reescrever - (UIViewController *) popViewControllerAnimated: (BOOL) animado

- (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;}

Ele funciona bem para mim: D

Eu tentei isso:

- (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];
}

A idéia é que a popping, navigationController do controlador de visualização está definido para zero. Então, se a vista era a desaparecer, e já tem uma navigationController, eu concluiu-se estalado. (Pode não funcionar em outros cenários).

Não é possível garantir que viewWillDisappear serão chamados popping, uma vez que não é mencionado nos docs. Eu tentei isso quando a vista era vista de cima, e abaixo vista de cima -. E funcionou em ambos

Boa sorte, Oded.

Você pode usar este:

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

subclasse UINavigationController e override 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
    }

}

Talvez você poderia usar NavigationBar de UINavigationBarDelegate:. Método de protocolo shouldPopItem

Tente fazer essa verificação em viewWillDisappear if ([self.navigationController.viewControllers indexOfObject: self] == NSNotFound) { // popping dessa visão tem happend. }

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top