特定の ViewController にポップできますか?
-
26-09-2019 - |
質問
ナビゲーションベースのアプリケーションを使用しています。最初の 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
}
}
関数を入れる 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)
ここに答えがあります。これは 100% 動作するコードです スイフト > 4.X