Pergunta

Estou usando o aplicativo baseado em navegação. Eu pressiono o First ViewController para o Second ViewController e do Second ViewController para o terceiro ViewController. Agora eu quero sair do terceiro ViewController para o First ViewController.Eu estou executando essa tarefa usando o código abaixo, mas meu aplicativo travou.

Por favor, qualquer corpo me dê algumas diretrizes adequadas. Não posso usar o pop para rootViewController porque é diferente ViewController. Desde já, obrigado...

No terceiro viewcontroler, escrevi isso:

FirstViewCtr *x=[[FirstViewCtr alloc] initWithNibName:@"FirstViewCtr" bundle:nil];
[self.navigationController popToViewController:x animated:NO];
Foi útil?

Solução

Ao escrever a primeira linha, você obtém os índices de todos os controladores de exibição e, a partir da segunda linha, chegará ao seu destino.

NSArray *array = [self.navigationController viewControllers];

[self.navigationController popToViewController:[array objectAtIndex:2] animated:YES];

Outras dicas

Uma abordagem mais segura:

- (void)turnBackToAnOldViewController{

    for (UIViewController *controller in self.navigationController.viewControllers) {

        //Do not forget to import AnOldViewController.h
        if ([controller isKindOfClass:[AnOldViewController class]]) { 

            [self.navigationController popToViewController:controller
                                                  animated:YES];
            return;
        }
    }
}

Caminho Swifty:

     let dashboardVC = navigationController!.viewControllers.filter { $0 is YourViewController }.first!
     navigationController!.popToViewController(dashboardVC, animated: true)
[self.navigationController popToViewController:[self.navigationController.viewControllers objectAtIndex:1] animated:YES];

Muitas vezes, é mais importante fazer isso de cima da pilha, então:

- (void)popToLast:(Class)aClass
{
    for (int i=self.navigationController.viewControllers.count-1; i>=0; i--)
    {
        UIViewController *vc = self.navigationController.viewControllers[i];
        if ([vc isKindOfClass:aClass])
        {
            [self.navigationController popToViewController:vc animated:YES];
            break;
        }
    }
}

E você chama isso

popToLast:[SomeViewController class];
- (void) RetunToSpecificViewController{

   for (UIViewController *controller in self.navigationController.viewControllers)
    {
           if ([controller isKindOfClass:[AnOldViewController class]])
           {
            //Do not forget to import AnOldViewController.h

                       [self.navigationController popToViewController:controller
                                                             animated:YES];
                        break;
            }
    }
}

Rápido e seguro Swift 3 versão:

if let vc = navigationController.viewControllers.filter({ $0 is SpecificViewControllerClass }).first {
  navigationController.popToViewController(vc, animated: true)
}

Seu código cria uma nova instância de uma visão que nunca foi empurrada para a pilha e tenta voltar a esse controlador.

Se você estiver voltando ao controlador de vista raiz, você pode usar popToRootViewControllerAnimated:

Se você estiver recuperando uma distância conhecida, você pode ligar popViewControllerAnimated: mais de uma vez. No seu exemplo, isso seria 2 controladores, para que as chamadas. Você poderia fazer a mesma coisa olhando viewControllers Para o controlador 2 do final e aparecendo para ele.

As sugestões acima são correções rápidas. Um cenário de prática recomendada seria passar no controlador para o qual você deseja retornar a cada controlador sucessivo que você pressiona. Primeiro, passa para o segundo, segundo passes que se referem ao terceiro, o terceiro aparece para a referência aprovada, que é o primeiro.

Com efeito, você está criando um controlador raiz temporário. Você pode subclasse UINavigationController e adicione um temporaryRoot propriedade e a popToTemporaryRootViewControllerAnimated: Método que apareceria na sua raiz temporária e a limparia. Quando empurra segundos pela primeira vez, ele também se estabeleceria como a raiz temporária, para que todo controlador da pilha não precise passar uma referência. Você teria que adicionar algumas verificações extras para não ter certeza de que nunca passa pelo temporarionte sem limpá -lo.

Depois de muito esforço, alguém criou uma extensão rápida de voltar a um controlador de exibição específico no Swift 3.0.

extension UINavigationController {

    func backToViewController(viewController: Swift.AnyClass) {

            for element in viewControllers as Array {
                if element.isKind(of: viewController) {
                    self.popToViewController(element, animated: true)
                break
            }
        }
    }
}

Chamada de método:

 self.navigationController?.backToViewController(viewController: YourViewController.self)

Implementado e testado em Swift 3.0

Abaixo está o método que pode ser útil para navegar para qualquer controlador de visualização específico:

func poptoSpecificVC(viewController : Swift.AnyClass){
        let viewControllers: [UIViewController] = self.navigationController!.viewControllers
        for aViewController in viewControllers {
            if aViewController.isKind(of: viewController) {
                self.navigationController!.popToViewController(aViewController, animated: true)
                break;
            }
        }
    }

Uso:

self.poptoSpecificVC(viewController: createIntervalVC.self)

eu penso isso .filter({...}).first é um pouco mais lento do que .first(where: {...}). Além disso, isso pode ser escrito com mais precisão para abordar apenas o UIViewControllers.

extension UINavigationController {
    func popToController<T: UIViewController>(_ type: T.Type, animated: Bool) {
        if let vc = viewControllers.first(where: { $0 is T }) {
            popToViewController(vc, animated: animated)
        }
    }
    func popToControllerOrToRootControllerIfNotInTheStack<T: UIViewController>(_ type: T.Type, animated: Bool) {
        if let vc = viewControllers.first(where: { $0 is T }) {
            popToViewController(vc, animated: animated)
        } else {
            popToRootViewController(animated: animated)
        }
    }
}

Atualizado para Swift 3:

usado abaixo do código simples, para o controlador de visualização POP para específico;

 for vc in self.navigationController!.viewControllers as Array {
          if vc.isKind(of: YourViewControllerName) {
               self.navigationController!.popToViewController(vc, animated: true)
               break
          }
    }

Swift 4 versão

if let viewController = navigationController?.viewControllers.first(where: {$0 is YourViewController}) {
      navigationController?.popToViewController(viewController, animated: false)
}

Você pode especificar outro filtro em .viewControllers.first De acordo com sua necessidade, por exemplo, digamos se você tiver o mesmo kind dos controladores de visão residentes no controlador de navegação, você pode especificar uma verificação adicional, como abaixo

  if let viewController = navigationController?.viewControllers.first(where: {
        if let current = $0 as? YourViewController {
             return current.someProperty == "SOME VALUE"
        }
       return false } ) {
            navigationController?.popToViewController(viewController, animated: false)
   }
for controller in self.navigationController!.viewControllers as Array {
        if controller.isKind(of: LoginVC.self) {
            _ =  self.navigationController!.popToViewController(controller, animated: true)
            break
        }
    }

Colocar função em UIViewController1. Ele verifica se específico UIViewController existe em UINavigationController então popToViewController se não pushViewController

func navigate(_ navVC: AnyClass, pushVC: UIViewController) {
    for obj in self.navigationController!.viewControllers {
        if obj.isMember(of: navVC) {
            self.navigationController!.popToViewController(obj, animated: true)
            return
        }
    }
    self.navigationController!.pushViewController(pushVC, animated: true)
}

Usar

self.navigate(ViewController.self, pushVC: self.storyboard?.instantiateViewController(withIdentifier: "ViewController") as! ViewController)

Eu tenho resposta aqui. Este é 100% de código de trabalho para Swift> 4.x

Como posso aparecer um controlador de exibição específico em Swift

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