ナビゲーションベースのアプリケーションを使用しています。最初の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];
最初の行を記述することにより、すべてのView Controllerのインデックスを取得し、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;
}
}
}
迅速かつ安全Swiftバージョン:
if let vc = navigationController.viewControllers.filter({ $0 is SpecificViewControllerClass }).first {
navigationController.popToViewController(vc, animated: true)
}
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)
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)
}
多くの努力の後、誰かが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)
.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)
}
}
}
コードは、スタックにプッシュされたことのないビューの新しいインスタンスを作成し、そのコントローラーにポップしようとします。
ルートView Controllerに戻る場合は、popToRootViewControllerAnimated:
を使用できます
既知の距離に戻っている場合は、popViewControllerAnimated:
を複数回呼び出すことができます。あなたの例では、2つのコントローラーが呼び出されます。コントローラー[2]のviewControllers
を最後から探してポップすることで、同じことを行うことができます。
上記の提案は簡単な修正です。ベストプラクティスのシナリオの1つは、プッシュする連続した各コントローラーに、戻りたいコントローラーを渡すことです。最初に自分自身を2番目に渡し、2番目にその参照を3番目に渡し、3番目に1番目に渡された参照にポップします。
実際には、一時的なルートコントローラーを作成しています。 UINavigationController
をサブクラス化し、temporaryRoot
プロパティと、一時ルートにポップしてクリアするpopToTemporaryRootViewControllerAnimated:
メソッドを追加できます。最初に秒をプッシュすると、スタック内のすべてのコントローラーが参照を渡す必要がないように、自身を一時的なルートとして設定します。 temporaryRootをクリアせずにポップしないようにするには、いくつかの追加チェックを追加する必要があります。
Swift 3:
特定のView Controllerへのポップのために、以下の簡単なコードで使用されます。
for vc in self.navigationController!.viewControllers as Array {
if vc.isKind(of: YourViewControllerName) {
self.navigationController!.popToViewController(vc, 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)
ここに答えがあります。これはSwift> 4.Xの100%動作するコードです
for controller in self.navigationController!.viewControllers as Array {
if controller.isKind(of: LoginVC.self) {
_ = self.navigationController!.popToViewController(controller, animated: true)
break
}
}