Ben Botvinick
Ben Botvinick

Reputation: 3345

Animate root view controller transition

I want to animate the transition between one root view controller and another. I could hypothetically perform a segue to the other view controller instead of switch roots, but if possible I would like to maintain the root view controller transition. Here's what I have to do this without animation.

let initialViewController = UIStoryboard.initialViewController(for: .main)
self.view.window?.rootViewController = initialViewController
self.view.window?.makeKeyAndVisible()

How would I do this with, say, an animation where the first controller slides up and away and reveals the second one?

Upvotes: 2

Views: 1573

Answers (2)

Yun CHEN
Yun CHEN

Reputation: 6648

An approach could be:
1. Set 2nd ViewController as root view controller.
2. Add 1st ViewController's view to 2nd Controller.
3. Remove 1st Controller's view with animation.

Code:

class View2Controller: UIViewController {

    var viewToAnimate:UIView?

    override func viewDidLoad() {
        super.viewDidLoad()

        // Do any additional setup after loading the view.

        if let view1Controller = self.storyboard?.instantiateViewController(withIdentifier: "View1Controller") {
            self.addChildViewController(view1Controller)
            self.view.addSubview(view1Controller.view)
            self.viewToAnimate = view1Controller.view
        }

        DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 1.5) {
            let frame = self.view.frame
            UIView.animate(withDuration: 1.0, animations: {
                self.viewToAnimate?.frame = CGRect(x: 0, y: -frame.height, width: frame.width, height: frame.height)
            }, completion: { (finished) in
                if finished {
                    self.viewToAnimate?.removeFromSuperview()
                }
            })
        }
    }

    override func viewDidLayoutSubviews() {
        super.viewDidLayoutSubviews()

        self.viewToAnimate?.frame = self.view.bounds
    }
}

Effect:
enter image description here

Source code on Github:
SlideUp Demo

Upvotes: 1

matt
matt

Reputation: 535889

You really shouldn't ever change your root view controller.

The way I deal with this, therefore, is that my root view controller is not my root view controller. Instead, I have a "secret" root view controller which is the real root view controller. It effectively does nothing; its view contains no interface. Its only job is to act as the parent to every other "root" view controller; it is a custom parent view controller (container view controller), and it always has one child view controller.

A moment's thought will show that now the problem is solved, because the business of replacing a child view controller and its view with another child view controller and its view, while transitioning with animation between the views, is straightforward and well-documented.

Upvotes: 0

Related Questions