Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unwind segue - going back multiple views

Lets say I have 3 ViewControllers - A, B and C. A shows B, B shows C. Then I want to go back to A without going through (visually) B (like home button). My problem currently is that when I unwind to A, for short period of time B is shown (viewWillAppear and etc. methods are called). How can I resolve this?

Note1: The above example is highly simplified compared to my real app navigation tree and for me using NavigationController as container to all A,B and C is not possible (or at least not desirable). Few of the reasons are in the middle of the transition there are complex embed segues and different custom transition(almost all animated transitions are absolutely different) across all views.

Note2: I found some pseudo solution with defining custom segue and using it as a Custom Unwind Segue. That is not desirable too because I want to use my already done transition animators.

Any help is highly appreciated.

like image 339
devfreak Avatar asked Jun 03 '15 13:06

devfreak


1 Answers

Please note that this is an amended answer - in response to the first comment below.

I have a possible solution which seems to work. But it may not be appropriate. I am not certain and offer it for consideration only.

The 3 view controllers are set up as described in the question (the second is red in order for me to notice whether it is visible during the unwind).

enter image description here

The unwind segue is created in the third view controller (C) by dragging to the Exit. Before doing this the required actions have to be added to the first and second view controllers.

enter image description here

enter image description here

Below is the code for the 3 view controllers. My fix - I am using a a global boolean called unwindCheck as a flag which is set true before the unwind but is otherwise false. If it is true then self.view.hidden = true in viewWillAppear for the second view controller. ie hidden during the unwind.

Please note that I have also added a second button on the third view controller - it calls the same unwind segue - the identifier property of which is set to "UnwindToFirstSegue". The second button is not a necessary part of this possible solution.

class FirstViewController: UIViewController {

    @IBAction func unwindToFirstViewController(segue: UIStoryboardSegue) {
    }

    override func viewDidLayoutSubviews() {
        unwindCheck = false
    }
}

class SecondViewController: UIViewController {

    override func viewWillAppear(animated: Bool) {
        super.viewWillAppear(animated)
        if unwindCheck == true {
            self.view.hidden = true
        }
    }

    @IBAction func unwindToSecondViewController(segue: UIStoryboardSegue) {
    }
}

class ThirdViewController: UIViewController {

    @IBAction func backToA(sender: AnyObject) {
        performSegueWithIdentifier("UnwindToFirstSegue", sender: self)
    }

    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
        if let identifier = segue.identifier{
            switch identifier {
            case "UnwindToFirstSegue":
                unwindCheck = true
            default:
                break
            }
        }
    }
}

The unwind segue's identifier can be set by selecting it in the Document Outline and then going to the Attributes inspector.

like image 171
simons Avatar answered Oct 13 '22 00:10

simons