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


当前回答

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

另一个选择是在视图控制器上实现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...
    }
}

其他回答

只需control +拖动栏项到func下面。魅力工作

@IBAction func done(sender: AnyObject) {
    if((self.presentingViewController) != nil){
        self.dismiss(animated: false, completion: nil)
        print("done")
    }
}

我通过以下方法做到了这一点:

斯威夫特3

override func didMoveToParentViewController(parent: UIViewController?) {
   super.didMoveToParentViewController(parent)

   if parent == nil {
      println("Back Button pressed.")
      delegate?.goingBack()
   }           
}

斯威夫特4

override func didMove(toParent parent: UIViewController?) {
    super.didMove(toParent: parent)

    if parent == nil {
        debugPrint("Back Button pressed.")
    }
}

不需要自定义后退按钮。

你可以子类化UINavigationController并重写popViewController(animated: Bool)。除了能够在那里执行一些代码,你还可以防止用户完全返回,例如提示保存或丢弃他当前的工作。

示例实现,其中您可以设置popHandler,由推送的控制器设置/清除。

class NavigationController: UINavigationController
{
    var popHandler: (() -> Bool)?

    override func popViewController(animated: Bool) -> UIViewController?
    {
        guard self.popHandler?() != false else
        {
            return nil
        }
        self.popHandler = nil
        return super.popViewController(animated: animated)
    }
}

以及来自跟踪未保存工作的推送控制器的示例使用情况。

let hasUnsavedWork: Bool = // ...
(self.navigationController as! NavigationController).popHandler = hasUnsavedWork ?
    {
        // Prompt saving work here with an alert

        return false // Prevent pop until as user choses to save or discard

    } : nil // No unsaved work, we clear popHandler to let it pop normally

作为一个很好的触摸,这也将被interactivePopGestureRecognizer调用,当用户试图返回使用滑动手势。

试试这个。

self.navigationItem.leftBarButtonItem?.target = "methodname"
func methodname ( ) {            
  //    enter code here
}

这个也试试。

override func viewWillAppear(animated: Bool) {
  //empty your array
}

在离开电流控制器之前,我需要显示警报。所以我是这样做的:

添加扩展UINavigationController与UINavigationBarDelegate 添加选择器到你的控制器导航

它的工作)

extension UINavigationController: UINavigationBarDelegate {
    public func navigationBar(_ navigationBar: UINavigationBar, shouldPop item: UINavigationItem) -> Bool {
        if let items = navigationBar.items, viewControllers.count < items.count {
            return true
        }

        let clientInfoVC = topViewController as? ClientInfoVC
        if clientInfoVC?.responds(to: #selector(clientInfoVC?.navigationShouldPopOnBack)) ?? false {
            clientInfoVC?.navigationShouldPopOnBack(completion: { isAllowPop in
                if isAllowPop {
                    DispatchQueue.main.async {
                        self.popViewController(animated: true)
                    }
                }
            })
        }

        DispatchQueue.main.async {
            self.popViewController(animated: true)
        }

        return false
    }
}

@objc func navigationShouldPopOnBack(completion: @escaping (Bool) -> ()) {
        let ok = UIAlertAction(title: R.string.alert.actionOk(), style: .default) { _ in
            completion(true)
        }
        let cancel = UIAlertAction(title: R.string.alert.actionCancel(), style: .cancel) { _ in
            completion(false)
        }
        let alertController = UIAlertController(title: "", message: R.string.alert.contractMessage(), preferredStyle: .alert)
        alertController.addAction(ok)
        alertController.addAction(cancel)
        present(alertController, animated: true, completion: nil)
    }