rootViewController 切替
iOS 13 から rootViewController の持ち方が SceneDelegate に代わりました。rootViewController切り替えの例です。
UIWindow, rootViewController の扱い
UIWindow, rootViewControllerは SceneDelegate
で管理します。
ビューコントローラーを切り替えたい場合は、次のようにします。
let sceneDelegate = UIApplication.shared.connectedScenes.first!.delegate as! SceneDelegate
sceneDelegate.window!.rootViewController = 新しいビューコントローラー
アニメーション効果
上記だけでと一瞬で画面が切り替わってしまうので、若干のアニメーション効果をつけてみます。
UIWindow間でのaddSubviewなどもできなくなってるっぽいので、やり方の例としてこんな風な処理をおこなっています。
1.遷移元の画面を画像化し、遷移先の画面に配置
2.rootViewController を入れ替える
3.アニメーションを利用して 1.の画像を透明化して削除
まず先にUIViewを画像化する処理を作成します。
extension UIView {
// UIVIewを画像化
func GetImage() -> UIImage {
// キャプチャする範囲を取得.
let rect = self.bounds
// ビットマップ画像のcontextを作成.
UIGraphicsBeginImageContextWithOptions(rect.size, false, 0.0)
let context: CGContext = UIGraphicsGetCurrentContext()!
// 対象のview内の描画をcontextに複写する.
self.layer.render(in: context)
// 現在のcontextのビットマップをUIImageとして取得.
let capturedImage : UIImage = UIGraphicsGetImageFromCurrentImageContext()!
// contextを閉じる.
UIGraphicsEndImageContext()
return capturedImage
}
}
rootViewController を切り替える処理を作成します。
extension UIViewController {
// rootViewController を入れ替える画面遷移
func moveTo(_ viewController: UIViewController) {
// 元画面の画像をセット
let imageView = UIImageView(image: self.view.GetImage())
viewController.view.addSubview(imageView)
// rootViewController入れ替え
let sceneDelegate = UIApplication.shared.connectedScenes.first!.delegate as! SceneDelegate
sceneDelegate.window!.rootViewController = viewController
// 元画面の画像を削除
UIView.animate(withDuration: 0.5, animations: {
imageView.alpha = 0.0
}, completion: { _ in
imageView.removeFromSuperview()
})
}
}
self.moveTo(遷移先のビューコントローラー)
で処理を実装できます。