我在从导航堆栈中删除 ViewController 时遇到问题?

I have issue to remove ViewController from Navigation stack?

我有 5 个 VC,我已成功从导航堆栈中删除 ViewController。但问题是当单击导航上的后退按钮时,它会移至上一个 VC 并在导航栏上显示已删除 VC。

例如:我有 5 个 VC:VC1、VC2、VC3、VC4、VC5。

现在我从 VC1 导航 -> VC2,..... VC4 -> VC5。我有自定义导航栏后退按钮标题。在这里,我要从堆栈中删除 VC4。

当点击 VC5 中的后退按钮时,它会直接移动到 VC3。但是导航栏是VC4。现在再次单击导航栏时,它会在同一个 VC.

中显示 VC3 个导航栏

如何解决这个问题。我想直接点击显示VC3和vc3导航栏

从导航堆栈中删除 VC 的代码:

guard let navigationController = self.navigationController else { return }
var navigationArray = navigationController.viewControllers // To get all UIViewController stack as Array
navigationArray.remove(at: navigationArray.count - 2) // To remove previous UIViewController
self.navigationController?.viewControllers = navigationArray

使用以下内容:

navigationController?.setViewControllers(navigationArray!, animated: true)

例如

guard let navigationController = self.navigationController else { return } 
var navigationArray = navigationController.viewControllers 
navigationArray.remove(at: navigationArray.count - 2) 
navigationController.setViewControllers(navigationArray!, animated: true)

来自docs

Use this method to update or replace the current view controller stack without pushing or popping each controller explicitly. In addition, this method lets you update the set of controllers without animating the changes, which might be appropriate at launch time when you want to return the navigation controller to a previous state.

If animations are enabled, this method decides which type of transition to perform based on whether the last item in the items array is already in the navigation stack. If the view controller is currently in the stack, but is not the topmost item, this method uses a pop transition; if it is the topmost item, no transition is performed. If the view controller is not on the stack, this method uses a push transition. Only one transition is performed, but when that transition finishes, the entire contents of the stack are replaced with the new view controllers. For example, if controllers A, B, and C are on the stack and you set controllers D, A, and B, this method uses a pop transition and the resulting stack contains the controllers D, A, and B.


编辑 1

推VC5时,使用如下代码

let vc = YourVC5()
var array = navigationController?.viewControllers
array?.removeLast()
array?.append(vc)
navigationController?.setViewControllers(array!, animated: true)

想法是,当您将 VC5 压入堆栈时,在压入之前我们将 VC4 从列表中排除,因此默认情况下 VC3 将位于 VC5 下方,您只需要调用 navigationController?.popViewController(animated: true) 和它应该直接弹出到 VC3

隐藏默认后退按钮并添加带有操作的自定义后退按钮:

override func viewDidLoad {
    super.viewDidLoad()
    self.navigationItem.hidesBackButton = true
        let customBackButton = UIBarButtonItem(title: "Back", style: UIBarButtonItem.Style.plain, target: self, action: #selector(back))
        self.navigationItem.leftBarButtonItem = customBackButton
}

使用 popToViewController 移回特定 viewcontroller:

@objc func back(sender: UIBarButtonItem) {
    guard let navigationController = self.navigationController else { return }
var navigationArray = navigationController.viewControllers // To get all 
self.navigationController!.popToViewController(navigationArray[navigationArray.count - 2], animated: true)
}

您可以使用 popToViewController(_:animated:)(正如 Prakash Shaiva 在上面回答的那样):

guard let navigationController = self.navigationController else { return }

var navigationArray = navigationController.viewControllers // To get all 
self.navigationController.popToViewController(navigationArray[navigationArray.count - 2], animated: true)

并尝试在方法 viewWillAppear(_:) 中为 VC3 更新 NavigationBar。

如果您使用的是自定义 NavigationBar,则需要使用自定义后退按钮单击 VC5 中的操作:-

@IBAction func btnBackAction(_ sender: UIButton) {
       let vc = VC3()
       self.navigationController.popToViewController(vc, animated: true)
 }

如果您可以使用默认 NavigationBar,则需要像这样在 VC5 的导航堆栈中删除 VC4:-

guard let navigationController = self.navigationController else { return }
var navigationArray = navigationController.viewControllers // To get all UIViewController stack as Array
navigationArray.remove(at: navigationArray.count - 2) // To remove previous UIViewController
self.navigationController?.viewControllers = navigationArray