2

I have 5 VC's, I'm successfully removing ViewController from navigation stack. But the problem is when click back button on navigation, it's moving into previous VC and it's showing removed VC on navigation bar.

Ex: I have 5 VC's: VC1, VC2, VC3, VC4, VC5.

Now I'm navigating from VC1 -> VC2, ..... VC4 -> VC5. And I have custom navigation bar back button title. Here I'm removing VC4 from stack.

When click back button in VC5 it's directly moving into VC3. But navigation bar is VC4. When click navigation bar once again now it's displaying VC3 navigation bar in same VC.

HOW TO resolve this issue. I want to display directly VC3 and vc3 navigation bar in single click.

Code to remove VC from Navigation stack:

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
1
  • 1
    I'm doing about the same things. See this for your ref. I'm not creating custom back button. Built in back button works. Commented Sep 24, 2019 at 11:41

4 Answers 4

3

Use the following:

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

E.g.

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

From the 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.


Edit 1

When you are pushing VC5, use the following code

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

The idea is when you push VC5 into stack, before pushing we are excluding VC4 from the list thus it will have VC3 beneath VC5 by default and you just need to call the navigationController?.popViewController(animated: true) and it should pop directly to VC3

Sign up to request clarification or add additional context in comments.

9 Comments

Difference between these two Lines ... self.navigationController?.viewControllers = navigationArray
No use.. guard let navigationController = self.navigationController else { return } var navigationArray = navigationController.viewControllers navigationArray.remove(at: navigationArray.count - 2) self.navigationController?.viewControllers = navigationArray self.navigationController?.setViewControllers(navigationArray, animated: true)
This is my code , ui updated but not working. getting same result.
You need to remove this line self.navigationController?.viewControllers = navigationArray
@iOS I've updated my answer with an example, please check
|
2

Hide default back button and add custom back button with action:

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
}

Use popToViewController to move back to specific 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)
}

5 Comments

Write this in VC5 when you want to move to VC3
When click on navigation bar back button I want to move directly in to VC3. It's default behaviour.. How to write it.
Add custom back button to navigation bar and write this code in the action of your custom back button
@iOS Updated my answer with custom back button... check
0

if you are using custom NavigationBar than you need to use custom back button click Action in VC5 :-

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

And if you can use Default NavigationBar than need to remove VC4 in navigation stack in VC5 like this:-

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

Comments

0

You can use popToViewController(_:animated:) (as Prakash Shaiva answered above):

guard let navigationController = self.navigationController else { return }

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

And try to update your NavigationBar in the method viewWillAppear(_:) for VC3.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.