Search code examples
iosswiftuinavigationcontrollersegueunwind-segue

iOS Swift Navigation unwind with redirection


I would like to implement the following: (I am using navigation controllers) enter image description here

View A has several options which determine which path to take. The first displays view B which will then display View C using navigation controllers. The tool bar's first item performs a unwind to View A. Which works. The second item in the tool bar, I would like to unwind not only to A but redirect to View E.

The code in A view controller looks like this:

@IBAction func unwindToHomeController(segue: UIStoryboardSegue) {
    self.performSegue(withIdentifier: "toPerson", sender: self)
}

When I click on the second item in the tool bar, View E is displayed but view A is immediately displayed after a brief delay.

How do I stop the display of View A?

Perhaps there is a better way.


Solution

  • You need to wait the animation finish to performSegue to E:

    class ViewController: UIViewController {
    
        @IBAction func unwindToA(segue: UIStoryboardSegue) {
        }
    
        @IBAction func unwindToE(segue: UIStoryboardSegue) {
            CATransaction.begin()
            CATransaction.setCompletionBlock { 
                self.performSegue(withIdentifier: "E", sender: nil)
            }
            CATransaction.commit()
        }
    
    }
    

    Normal unwind

    UPDATED To avoid the flashing showing A while pushing E

    1) Remove the unwindToE function:

    extension ViewController {
    
        @IBAction func unwindToA(segue: UIStoryboardSegue) {
        }
    
    //  @IBAction func unwindToE(segue: UIStoryboardSegue) {
    //      CATransaction.begin()
    //      CATransaction.setCompletionBlock { 
    //          self.performSegue(withIdentifier: "E", sender: nil)
    //      }
    //      CATransaction.commit()
    //  }
    
    }
    

    2) Create a custom segue:

    class MyUnwindSegue: UIStoryboardSegue {
    
        override func perform() {
    
            guard let nav = source.navigationController else { return }
            guard let root = nav.viewControllers.first else { return }
            let viewControllers = [root, destination]
            nav.setViewControllers(viewControllers, animated: true)
    
        }
    
    }
    

    3) Update the segue to MyUnwindSegue in storyboard (make sure the Module is selected to your project module rather than empty):

    Using custom unwind segue