在Swift中导航控制器中弹出两个视图控制器

64
我发现了许多使用Objective-C从UINavigationController弹回2个UIViewControllers的方法,然而当我尝试将其转换为Swift时似乎不起作用。 弹回到UIViewController的最佳方法是什么? 任何指导都将不胜感激 谢谢

与ObjC非常相似:复制UINavigationControllerviewControllers数组,从该数组中删除最后两个元素,并将viewControllers设置为修改后的数组。还有一个setViewControllers(_:animated:)方法可以包含弹出动画。 - fluidsonic
3
你可以在viewControllers数组中找到倒数第二个视图控制器,然后使用popToViewController方法来避免重写整个视图控制器栈。 - Aaron Wojnowski
你可以通过他的类弹出一个控制器 https://dev59.com/lF0a5IYBdhLWcg3wuKw7#40314079 - PabloR
9个回答

176

扩展我的评论,找到 viewControllers 数组中的倒数第二个视图控制器,然后使用 popToViewController 来避免覆盖整个视图控制器堆栈。

示例(假设导航控制器有多个视图控制器):

func backTwo() {
    let viewControllers: [UIViewController] = self.navigationController!.viewControllers as [UIViewController]
    self.navigationController!.popToViewController(viewControllers[viewControllers.count - 3], animated: true)
}

Objective-C

NSArray *viewControllers = [self.navigationController viewControllers];
[self.navigationController popToViewController:viewControllers[viewControllers.count - 3] animated:YES];

这个很好用,谢谢!跟进问题:当它弹出到正确的视图控制器时,它首先将横向视图旋转为纵向,然后再弹出。有没有办法在弹出之前不旋转横向视图? - candidaMan
7
哇,谢谢你,Aaron!这个方法完美地解决了我的问题!奇怪的是,我不得不把 viewControllers.count - 3 来返回两步,但现在它非常有效! - Camillo
viewControllers数组也包括当前的UIViewController,因此您必须使用viewControllers.count - 3。 - haris

34

我编写了一个UIViewController扩展(适用于Swift 3+),

你可以像这样使用:

/// pop back n viewcontroller
func popBack(_ nb: Int) {
    if let viewControllers: [UIViewController] = self.navigationController?.viewControllers {
        guard viewControllers.count < nb else {
            self.navigationController?.popToViewController(viewControllers[viewControllers.count - nb], animated: true)
            return
        }
    }
}

用法:

self.popBack(3)

将奖励取消应用于特定的视图控制器

/// pop back to specific viewcontroller
func popBack<T: UIViewController>(toControllerType: T.Type) {
    if var viewControllers: [UIViewController] = self.navigationController?.viewControllers {
        viewControllers = viewControllers.reversed()
        for currentViewController in viewControllers {
            if currentViewController .isKind(of: toControllerType) {
                self.navigationController?.popToViewController(currentViewController, animated: true)
                break
            }
        }
    }
}

使用方法:

self.popBack(toControllerType: MyViewController.self)

13

user5320485 在 Swift3 中的回答。

let viewControllers = self.navigationController!.viewControllers as [UIViewController];
for aViewController:UIViewController in viewControllers {
    if aViewController.isKind(of: AdCreateViewController.self) {
        _ = self.navigationController?.popToViewController(aViewController, animated: true)
    }
}

11

你可以在Swift 2.0中动态地弹出多个视图控制器

let allViewController: [UIViewController] = self.navigationController!.viewControllers as [UIViewController];

                        for aviewcontroller : UIViewController in allViewController
                        {
                            if aviewcontroller .isKindOfClass(YourDestinationViewControllerName)
                            {
                             self.navigationController?.popToViewController(aviewcontroller, animated: true)
                            }
                        }

9

以下是Swift 4版的UINavigationController扩展,参考@Maximelc的答案:

extension UINavigationController {

    func popBack(_ nb: Int) {
        let viewControllers: [UIViewController] = self.viewControllers
        guard viewControllers.count < nb else {
            self.popToViewController(viewControllers[viewControllers.count - nb], animated: true)
            return
        }
    }

    /// pop back to specific viewcontroller
    func popBack<T: UIViewController>(toControllerType: T.Type) {
        var viewControllers: [UIViewController] = self.viewControllers
        viewControllers = viewControllers.reversed()
        for currentViewController in viewControllers {
            if currentViewController .isKind(of: toControllerType) {
                self.popToViewController(currentViewController, animated: true)
                break
            }
        }
    }

 }

2
用法:self.navigationController?.popBack(1) self.navigationController?.popBack(toControllerType: YourViewController.self) - Naresh

3

如果您想弹出特定的视图控制器,可以将示例代码中的DestinationViewController替换为您的视图控制器来搜索该视图控制器。

func moveToDestinationViewController() {
    let viewController = self.navigationController?.viewControllers.first { $0 is DestinationViewController }
    guard let destinationVC = viewController else { return }
    self.navigationController?.popToViewController(destinationVC, animated: true)
}

1
这里是另一个稍微“傻瓜式”的版本:

extension UINavigationController {
    func popBack(_ count: Int) {
        guard count > 0 else {
            return assertionFailure("Count can not be a negative value.")
        }
        let index = viewControllers.count - count - 1
        guard index > 0 else {
            return assertionFailure("Not enough View Controllers on the navigation stack.")
        }
        popToViewController(viewControllers[index], animated: true)
    }
}

1
 let allViewControllers : [UIViewController] = self.navigationController!.viewControllers as [UIViewController]
        self.navigationController?.popToViewController(allViewControllers[allViewControllers.count-3], animated: true)

0

我写了一个辅助工具,让它变得更容易:

import Foundation
import UIKit

class NavigationHelper {

    static func back(number: Int, from viewControlller : UIViewController) {
        let viewsBack = number + 1
        let viewControllers: [UIViewController] = viewControlller.navigationController!.viewControllers as [UIViewController]
        viewControlller.navigationController!.popToViewController(viewControllers[viewControllers.count - viewsBack], animated: true)
    }

    static func back(number: Int, from viewControlller: UITableViewController) {
        let viewsBack = number + 1
        let viewControllers: [UIViewController] = viewControlller.navigationController!.viewControllers as [UIViewController]
        viewControlller.navigationController!.popToViewController(viewControllers[viewControllers.count - viewsBack], animated: true)
    }
}

例如,在您的ViewController中,您可以使用NavigationHelper.back(number: 1, from: self)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接