web-dev-qa-db-ja.com

特定のViewControllerにポップできますか?

ナビゲーションベースのアプリケーションを使用しています。最初のViewControllerを2番目のViewControllerにプッシュし、2番目のViewControllerから3番目のViewControllerにプッシュします。次に、3番目のViewControllerから1番目のViewControllerにポップします。次のコードを使用してこのタスクを実行していますが、アプリケーションがクラッシュしました。

体に適切なガイドラインを教えてください。 rootViewControllerにポップを使用することはできません。これは、viewControllerが異なるためです。前もって感謝します...

サードViewControlerで私はこれを書いた:

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

最初の行を記述することにより、すべてのView Controllerのインデックスを取得し、2行目から目的地まで到達します。

NSArray *array = [self.navigationController viewControllers];

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

より安全なアプローチ:

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

迅速な方法:

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

多くの場合、スタックの最上部からそれを行うことがより重要です。

- (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];
6
Leszek Zarna
- (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;
            }
    }
}
5
Mahendra Y

迅速かつ安全Swiftバージョン:

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

Swift 3.で実装およびテスト済み

以下は、特定のView Controllerにナビゲートするのに役立つメソッドです。

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

使用法:

self.poptoSpecificVC(viewController: createIntervalVC.self)
1
Ketan P

Swift 4バージョン

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

必要に応じて、.viewControllers.firstに別のフィルターを指定できます。たとえば、Navigation Controllerにあるkindと同じView Controllerがある場合、次のような追加チェックを指定できます。

  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
Umair

多くの努力の後、誰かがSwift 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
            }
        }
    }
}

メソッド呼び出し:

 self.navigationController?.backToViewController(viewController: YourViewController.self)
1
Ved Rauniyar

.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)
        }
    }
}
1

コードは、スタックにプッシュされたことのないビューの新しいインスタンスを作成し、そのコントローラーにポップしようとします。

ルートView Controllerに戻る場合は、popToRootViewControllerAnimated:を使用できます

既知の距離に戻っている場合は、popViewControllerAnimated:を複数回呼び出すことができます。あなたの例では、2つのコントローラーが呼び出されます。コントローラー[2]のviewControllersを最後から探してポップすることで、同じことを行うことができます。

上記の提案は簡単な修正です。ベストプラクティスのシナリオの1つは、プッシュする連続した各コントローラーに、戻りたいコントローラーを渡すことです。最初に自分自身を2番目に渡し、2番目にその参照を3番目に渡し、3番目に1番目に渡された参照にポップします。

実際には、一時的なルートコントローラーを作成しています。 UINavigationControllerをサブクラス化し、temporaryRootプロパティと、一時ルートにポップしてクリアするpopToTemporaryRootViewControllerAnimated:メソッドを追加できます。最初に秒をプッシュすると、スタック内のすべてのコントローラーが参照を渡す必要がないように、自身を一時的なルートとして設定します。 temporaryRootをクリアせずにポップしないようにするには、いくつかの追加チェックを追加する必要があります。

1
drawnonward

Swift 3:

特定のView Controllerへのポップのために、以下の簡単なコードで使用されます。

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

UIViewControllerに関数を配置します。1. UIViewControllerに特定のUINavigationControllerが存在するかどうかをチェックし、次にpopToViewControllerまたは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)
}

使用する

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

ここに答えがあります。これはSwift> 4.Xの100%動作するコードです

Swiftで特定のView Controllerをポップする方法

0
Ashu
for controller in self.navigationController!.viewControllers as Array {
        if controller.isKind(of: LoginVC.self) {
            _ =  self.navigationController!.popToViewController(controller, animated: true)
            break
        }
    }
0
Ankit Vyas