2
votes

I'm using storyboard and have 3 VCs. When I'm on VC3 I would like the back button to skip VC2 and go to VC1.

I tried the following which works but VC2 flashes before I get to VC1

override func viewWillDisappear(_ animated: Bool) {
    self.navigationController?.popViewController(animated: true)
}

My custom back code:

override func viewDidLoad() {
    super.viewDidLoad()
    self.navigationController?.navigationBar.setBackgroundImage(UIImage(), for: UIBarMetrics.default)
    self.navigationController?.navigationBar.shadowImage = UIImage()
    self.navigationController?.navigationBar.isTranslucent = true
    self.navigationController?.navigationBar.backIndicatorImage = UIImage(named: "arrow_back")
    self.navigationController?.navigationBar.backIndicatorTransitionMaskImage = UIImage(named: "arrow_back")
    self.navigationItem.backBarButtonItem = UIBarButtonItem(title: "", style: .plain, target: nil, action: #selector(self.backPressed(_:)))
    self.navigationController?.navigationBar.barStyle = .black  
}

@objc func backPressed(_ sender: Any){
    print("here")
    self.navigationController?.popToRootViewController(animated: false)
}
3
try using navigationController?.popToRootViewController(animated: true) when you press back in VC3. - Vikky
Use an unwind segue - Paulw11
How do you push VC3? Using storyboard segue? - RajeshKumar R
@Vikky how do I asign that piece of code to my back button? - Sebastien Desemberg
Just write code in @IBAction of back button in your VC3. But I think you are using segue?. - Vikky

3 Answers

1
votes

change in viewDidLoad

override func viewDidLoad() {
    super.viewDidLoad()
    self.navigationController?.navigationBar.setBackgroundImage(UIImage(), for: UIBarMetrics.default)
    self.navigationController?.navigationBar.shadowImage = UIImage()
    self.navigationController?.navigationBar.isTranslucent = true
    self.navigationController?.navigationBar.backIndicatorImage = UIImage(named: "arrow_back")
    self.navigationController?.navigationBar.backIndicatorTransitionMaskImage = UIImage(named: "arrow_back")

     var backButton = UIBarButtonItem(title: "", style: .plain, target: self, action: #selector(backPressed(_:)))
     navigationController?.navigationBar.topItem?.backBarButtonItem = backButton
    self.navigationController?.navigationBar.barStyle = .black  
}

Add if you want to go at very first controller use

@objc func backPressed(_ sender: Any){
     self.navigationController?.popToRootViewController(animated: true) 
}

and if its not fist view controller in navigation controller

@objc func backPressed(_ sender: Any){
     let controllerToBeReached = navigationController!.viewControllers.filter { $0 is YourViewController }.first!
     navigationController!.popToViewController(controllerToBeReached, animated: true)
}
0
votes

If you dont want to see VC2 flashed before VC1 appears, and in case VC1 is the root then just set animated = false

Override action back from your VC3 then use this: self.navigationController?.popToRootViewController(animated: false)

0
votes

In Your code back Button Automatically perform popToViewController first than viewWillDisappear method call so that you flashes on VC2

In VC3 add Back BarButtonitem for perform action for go to VC3 to VC1

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
    }

Here method of back UIBarButtonItem

@objc func back(sender: UIBarButtonItem) {
    let vc = VC1()
    self.navigationController.popToViewController(vc, animated: true) 
}