質問

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

どなたか適切なガイドラインを教えてください。viewControllerが異なるため、rootViewControllerにpopを使用できません。前もって感謝します...

Third ViewControler では次のように書きました。

FirstViewCtr *x=[[FirstViewCtr alloc] initWithNibName:@"FirstViewCtr" bundle:nil];
[self.navigationController popToViewController:x animated:NO];
役に立ちましたか?

解決

最初の行を書くことで、すべてのビュー コントローラーのインデックスを取得し、2 行目から宛先に到達します。

NSArray *array = [self.navigationController viewControllers];

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

他のヒント

より安全なアプローチ:

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

迅速な方法:

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

多くの場合、これをスタックの最上位から行うことがより重要であるため、次のようにします。

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

早くて安全 スイフト3 バージョン:

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

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

ルートビューコントローラーに戻っている場合は、次のように使用できます。 popToRootViewControllerAnimated:

既知の距離から戻ってくる場合は、電話をかけることができます popViewControllerAnimated: 一回以上。あなたの例では、それは 2 つのコントローラーになります。調べても同じことができます viewControllers コントローラー 2 を端から押してそこにポップします。

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

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

多くの努力の末、誰かが Swift 3.0 の特定のビュー コントローラーに戻る Swift 拡張機能を作成しました。

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)

実装およびテスト済み スイフト3.0

以下は、特定の 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)

私はそう思います .filter({...}).first よりも少し遅いです .first(where: {...}). 。また、これは UIViewController のみを処理するようにより正確に記述することもできます。

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

Swift 3 用に更新されました:

単純なコードの下で、特定のビュー コントローラーにポップするために使用されます。

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

スイフト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)
   }
for controller in self.navigationController!.viewControllers as Array {
        if controller.isKind(of: LoginVC.self) {
            _ =  self.navigationController!.popToViewController(controller, animated: true)
            break
        }
    }

関数を入れる UIViewController1.特定かどうかを確認します 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)

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

Swiftで特定のView Controllerをポップするにはどうすればよいですか

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top