【Swift】RootViewControllerでアニメーションつきの画面遷移

## はじめに
RootViewControllerを使ったアニメーションつきの画面遷移を簡単にまとめます
![RootViewController.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/592713/cbdf4b41-307d-8198-f150-33997d887d7b.gif)


## Storyboard
![スクリーンショット 2020-09-01 12.48.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/592713/51eba30e-e7bc-8abc-8e35-535d2619321e.png)

ViewControllerとSecondViewControllerを置いてるだけです。
StoryboardIDも設定しましょう。忘れるとクラッシュします。

## SceneDelegate
RootViewControllerの処理をAppDelegateに書いてる記事が多いですがiOS13以降の場合はSceneDelegateに記述します。


```Swift:SceneDelegate.Swift
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
    guard let scen = (scene as? UIWindowScene) else { return }
    window = UIWindow(windowScene: scen)
    window!.backgroundColor = .white

    let storyboard = UIStoryboard(name: "Main", bundle: nil)
    let topviewController = storyboard.instantiateViewController(withIdentifier: "ViewController")
    window!.rootViewController = topviewController
    window!.makeKeyAndVisible()

    if let appDelegate = UIApplication.shared.delegate as? AppDelegate {
        appDelegate.window = window
    }
}

func switchViewController(viewController: UIViewController) {
    UIView.transition(with: self.window!, duration: 0.5, options: .transitionCrossDissolve, animations: {
        let oldState: Bool = UIView.areAnimationsEnabled
        UIView.setAnimationsEnabled(false)
        self.window?.rootViewController = viewController
        UIView.setAnimationsEnabled(oldState)
    }, completion: nil)
}
```
## ViewController

```Swift:ViewController.Swift
final class ViewController: UIViewController {

    let switchButton = UIButton()

    override func viewDidLoad() {
        super.viewDidLoad()

        prepareUI()
    }

    private func prepareUI() {
        // わかりやすくするためにViewControllerの背景色を変更
        view.backgroundColor = .systemTeal

        // UIButton作成
        switchButton.frame.size = CGSize(width: 200, height: 100)
        switchButton.center = view.center
        switchButton.backgroundColor = .lightGray
        switchButton.setTitle("Next Button", for: .normal)
        switchButton.addTarget(self, action: #selector(didTapSwitchButton(sender:)), for:.touchUpInside)
        view.addSubview(switchButton)
    }

    // switchButtonを押したときに実行される処理
    @objc private func didTapSwitchButton(sender: UIButton) {
        print("Nextボタンが押されたよ")
        let sceneDelegate = (UIApplication.shared.connectedScenes.first as? UIWindowScene)?.delegate as? SceneDelegate
        let storyboard = UIStoryboard(name: "Main", bundle: nil)
        // StoryboardIDをwithIdentifierで指定します
        let vc = storyboard.instantiateViewController(withIdentifier: "SecondViewController")
        sceneDelegate?.switchViewController(viewController: vc)
    }
}

```
## SecondViewController

```Swift:SecondViewController.Swift
final class ViewController: UIViewController {

    let backButton = UIButton()

    override func viewDidLoad() {
        super.viewDidLoad()

        prepareUI()
    }

    private func prepareUI() {
        view.backgroundColor = .lightGray

        backButton.frame.size = CGSize(width: 200, height: 100)
        backButton.center = view.center
        backButton.backgroundColor = .systemTeal
        backButton.setTitle("Back Button", for: .normal)
        backButton.addTarget(self, action: #selector(didTapBackButton(sender:)), for:.touchUpInside)
        view.addSubview(backButton)
    }

    @objc private func didTapBackButton(sender: UIButton) {
        print("Backボタンが押されたよ")
        let sceneDelegate = (UIApplication.shared.connectedScenes.first as? UIWindowScene)?.delegate as? SceneDelegate
        let storyboard = UIStoryboard(name: "Main", bundle: nil)
        let viewController = storyboard.instantiateViewController(withIdentifier: "ViewController")
        sceneDelegate?.switchViewController(viewController: viewController)
    }
}
```

ここまででビルドしてみましょう。
ボタンを押すと冒頭のGIFのようなアニメーションつきの画面遷移ができるかと思います。