1
votes

I want to create something similar to done/edit page for the Contacts app. It seems that there is a change in a view behind a modal view, however I'm not sure how that produce that behavior.

Here is what I've looked at so far:

iOS: Switch view controller behind current modal view controller? It seems like this post has a correct answer. However, I'm not sure what he means by making the root view controller a delegate of the modal view and what it means to call a delegate method.

Here is what I want to accomplish:

Imagine a vc1 that is embedded in a navigation controller. I tap a button on vc1 which causes vc2 to be presented modally. When you press "Done" on vc2, it dismisses the modal view, vc2, and presents vc3. When you tap a back button on vc3, it goes back to vc1.

Here is the current behavior:

I can make vc2 show on top of vc1 modally. But when the "Done" button is pressed on vc2, it just goes back to vc1 instead of going to vc3 then, when tapped "Back", goes to vc1.

Here is what I've tried already:

I tried segue from vc1 to vc3 without animation, and then modally segue to v2. This kind of works with extremely ugly transition and it causes this Presenting view controllers on detached view controllers is discouraged error to show. Also, I've tried different combinations of unwindToSegue methods, but I couldn't figure that out either.

Any help would be much appreciated! Thank you so much for your time :)

1

1 Answers

1
votes

You make the root view controller (vc1) a delegate of your modal view controller by making a protocol in vc1, and having it as a property of your modal view controller. When you dismiss the modal view controller, call one of the delegate methods. Something like this might work for you:

vc1:

protocol Vc1Delegate: class {
    func pushToVc3()
}

class Vc1: UIViewController, Vc1Delegate
{
    override func viewDidLoad() {
        super.viewDidLoad()
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }

    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
        if segue.identifier == "Vc2Modal" {
            if let _vc2 = segue.destinationViewController as? Vc2 {
                _vc2.delegate = self
            }
        }
    }

    @IBAction func showVc2Modal() {
        performSegueWithIdentifier("Vc2Modal", sender: nil)
    }

    // MARK: Vc1Delegate

    func pushToVc3() {
        performSegueWithIdentifier("Vc3PushWithoutAnimation", sender: nil)
    }
}

Vc2:

class Vc2: UIViewController
{
    weak var delegate: Vc1Delegate?

    override func viewDidLoad() {
        super.viewDidLoad()
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }

    @IBAction func dismiss() {
        delegate?.pushToVc3()
        dismissViewControllerAnimated(true, completion: nil)
    }
}