Могу ли я попасть в конкретный ViewController? - PullRequest
47 голосов
/ 12 июня 2010

Я использую приложение на основе навигации. Я помещаю Первый ViewController во Второй ViewController и из Второго ViewController в Третий ViewController. Теперь я хочу перейти от третьего ViewController к первому ViewController. Я выполняю эту задачу, используя приведенный ниже код, но мое приложение упало.

Пожалуйста, дайте мне какое-нибудь тело. Я не могу использовать pop для rootViewController, потому что это другой viewController. Заранее спасибо ...

В третьем контроллере вида я написал это:

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

Ответы [ 15 ]

93 голосов
/ 12 июня 2010

В первой строке вы получаете индексы всех контроллеров представления, а со второй строки вы достигнете своего пункта назначения.

NSArray *array = [self.navigationController viewControllers];

[self.navigationController popToViewController:[array objectAtIndex:2] animated:YES];
75 голосов
/ 21 февраля 2013

Более безопасный подход:

- (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;
        }
    }
}
15 голосов
/ 21 декабря 2015

Swifty way:

     let dashboardVC = navigationController!.viewControllers.filter { $0 is YourViewController }.first!
     navigationController!.popToViewController(dashboardVC, animated: true)
7 голосов
/ 28 мая 2016
[self.navigationController popToViewController:[self.navigationController.viewControllers objectAtIndex:1] animated:YES];
6 голосов
/ 04 сентября 2013

Часто более важно сделать это с вершины стека, поэтому:

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

и вы называете это

popToLast:[SomeViewController class];
5 голосов
/ 28 апреля 2015
- (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;
            }
    }
}
2 голосов
/ 07 июня 2017

Быстрый и безопасный Swift 3 версия:

if let vc = navigationController.viewControllers.filter({ $0 is SpecificViewControllerClass }).first {
  navigationController.popToViewController(vc, animated: true)
}
1 голос
/ 01 августа 2018

Swift 4 версия

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

Вы можете указать другой фильтр на .viewControllers.first в соответствии с вашими потребностями, например, скажем, если у вас есть те же kind контроллеры представления, находящиеся в навигационном контроллере, тогда вы можете указать дополнительную проверку, как показано ниже

  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)
   }
1 голос
/ 16 ноября 2017

Обновлено для Swift 3:

, используемый ниже простого кода, для всплывающего окна с конкретным контроллером вида;

 for vc in self.navigationController!.viewControllers as Array {
          if vc.isKind(of: YourViewControllerName) {
               self.navigationController!.popToViewController(vc, animated: true)
               break
          }
    }
1 голос
/ 24 октября 2017

Я думаю, что .filter({...}).first немного медленнее, чем .first(where: {...}). Также это может быть написано более точно для адресов только 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)
        }
    }
}
...