我需要执行一个动作(清空一个数组),当UINavigationController的后退按钮被按下,而按钮仍然导致堆栈上的前一个ViewController出现。我如何使用swift来实现这一点?


当前回答

你可以在视图控制器中做一些事情

override func navigationShouldPopOnBackButton() -> Bool {
    self.backAction() //Your action you want to perform.
    return true
}

完整回答使用 当导航条上的“后退”按钮被按下时进行检测

其他回答

你可以简单地从堆栈中删除不必要的控制器,就像这样:

self.navigationController?.viewControllers.removeAll(where: {
        $0 is FirstViewController || $0 is SecondWithPinController
    })

NO

override func willMove(父控件:UIViewController?) {}

即使你在segue到覆盖这个方法的视图控制器,这个也会被调用。其中,检查parent是否为nil或not不是确保移动回正确的UIViewController的精确方法。为了准确地确定UINavigationController是否正确地导航回呈现当前的UIViewController,你将需要遵守UINavigationControllerDelegate协议。

YES

注意:MyViewController只是你想要检测返回的UIViewController的名称。

1)在你的文件顶部添加UINavigationControllerDelegate。

class MyViewController: UIViewController, UINavigationControllerDelegate {

2)添加一个属性到你的类,它将跟踪你正在segue的UIViewController。

class MyViewController: UIViewController, UINavigationControllerDelegate {

var previousViewController:UIViewController

3)在MyViewController的viewDidLoad方法中为你的UINavigationController分配self作为委托。

override func viewDidLoad() {
    super.viewDidLoad()
    self.navigationController?.delegate = self
}

3)在你segue之前,将之前的UIViewController分配为这个属性。

// In previous UIViewController
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if segue.identifier == "YourSegueID" {
        if let nextViewController = segue.destination as? MyViewController {
            nextViewController.previousViewController = self
        }
    }
}

4)并遵循UINavigationControllerDelegate的MyViewController中的一个方法

func navigationController(_ navigationController: UINavigationController, willShow viewController: UIViewController, animated: Bool) {
    if viewController == self.previousViewController {
        // You are going back
    }
}
override func willMove(toParent parent: UIViewController?)
{
    super.willMove(toParent: parent)
    if parent == nil
    {
        print("This VC is 'will' be popped. i.e. the back button was pressed.")
    }
}

将按钮替换为另一个答案中建议的自定义按钮可能不是一个好主意,因为您将失去默认的行为和样式。

另一个选择是在视图控制器上实现viewWillDisappear方法,并检查名为isMovingFromParentViewController的属性。如果那个属性为真,它意味着视图控制器正在消失,因为它正在被移除(弹出)。

应该是这样的:

override func viewWillDisappear(_ animated: Bool) {
    super.viewWillDisappear(animated)

    if self.isMovingFromParentViewController {
        // Your code...
    }
}

在swift 4.2中

override func viewWillDisappear(_ animated: Bool) {
    super.viewWillDisappear(animated)

    if self.isMovingFromParent {
        // Your code...
    }
}

如果你想有后退按钮和后退箭头,你可以使用下面的图片和代码

backArrow.png backArrow@2x.png backArrow@3x.png

override func viewDidLoad() {
    super.viewDidLoad()
    let customBackButton = UIBarButtonItem(image: UIImage(named: "backArrow") , style: .plain, target: self, action: #selector(backAction(sender:)))
    customBackButton.imageInsets = UIEdgeInsets(top: 2, left: -8, bottom: 0, right: 0)
    navigationItem.leftBarButtonItem = customBackButton
}

func backAction(sender: UIBarButtonItem) {
    // custom actions here
    navigationController?.popViewController(animated: true)
}