サトリク
この記事では、モーダル表示してから、dismissで戻るときに、処理を画面遷移元で処理する際に少し手間取ったので、記事にします。
動作環境
item | Version |
---|---|
Swift | 5.2.2 |
Xcode | 11.4.1 |
やりたいこと
モーダル表示してから、閉じるを押したときに、処理を実行したい。
以下の動画のように、閉じるボタンを押したときに、遷移元の背景色を変更するなどの処理をしたい。
iOS12以前の対応
override func viewDidAppear(_ animated: Bool) { //やりたい処理 }
遷移元のViewControllerの中で上記のメソッド内に処理を書くと、モーダル表示の閉じるを押したときに、処理が行われます。
しかし、iOS13以降このように、するだけでは処理できなくなりました。
iOS12とiOS13のモーダル表示の違い
iOS12のモーダル表示は、単に下から上にアニメーションし画面遷移します。
しかし、iOS13のモーダル表示はiOS12と違い、中途半端なところで遷移が終わります。また、閉じるボタンを押さなくても、したにドラッグすることで、遷移元に戻ることができます。
iOS13以降の対応
対応は大きく分けて以下の2つあります。
- フルスクリーンにする方法
presentationControllerDidDismiss
で実装する方法
フルスクリーンにする方法
iOS12とiOS13の違いは、先ほども言った通り、フルスクリーンになるかならないかの違いです。
iOS13でも、storyboardから「presentation」を「FullScreen」に変更するだけで、iOS12のような挙動にできます。
こうすることで、iOS13でもviewDidAppear
メソッドでも呼ばれるようになり、処理を書き込むことができます。
サトリク
これが一番手っ取り早い対処法だと思います。
実際にフルスクリーンにする方法で実装してみる
①ボードのバーをクリック
② (Attributes Inspector)を選択
③「presentation」を「FullScreen」に変更
ViewController(遷移元)に以下の記述をする
override func viewDidAppear(_ animated: Bool) { //処理 }
これで呼ばれると思います。
presentationControllerDidDismiss
で実装する方法
フルスクリーンにはしたくないなら、以下の対応をするといいでしょう。
遷移元の処理:モーダル表示する際に以下のような記述をする
以下のように、nextView.presentationController?.delegate = self
を追加する
let nextView = storyboard?.instantiateViewController(identifier: "Next") as! NextViewController nextView.presentationController?.delegate = self present(nextView, animated: true, completion: nil)
遷移元の処理:extensionで以下のように実装する
extension ViewController: UIAdaptivePresentationControllerDelegate { func presentationControllerDidDismiss(_ presentationController: UIPresentationController) { } }
遷移先の処理:extensionで、以下のように実装する
extension ModalViewController { override func dismiss(animated flag: Bool, completion: (() -> Void)? = nil) { super.dismiss(animated: flag, completion: completion) guard let presentationController = presentationController else { return } presentationController.delegate?.presentationControllerDidDismiss?(presentationController) } }
これで、presentationControllerDidDismiss
に処理を書くと、呼ばれるようになります。
実際にpresentationControllerDidDismissで実装する方法で実装してみる
@IBAction func toNextBtn(_ sender: Any) { let nextView = storyboard?.instantiateViewController(identifier: "Next") as! NextViewController nextView.presentationController?.delegate = self //←追加する present(nextView, animated: true, completion: nil) }
画面遷移の仕方がわからない方は、こちらの記事をオススメします。
【Swift5/Xcode】画面遷移のチートシート。Segueを画面遷移とSegueを使わない画面遷移を徹底解説extension ViewController: UIAdaptivePresentationControllerDelegate { func presentationControllerDidDismiss(_ presentationController: UIPresentationController) { //処理 self.view.backgroundColor = UIColor.red } }
やりたい処理をこのメソッドの中に書いてください。
extension NextViewController { override func dismiss(animated flag: Bool, completion: (() -> Void)? = nil) { super.dismiss(animated: flag, completion: completion) guard let presentationController = presentationController else { return } presentationController.delegate?.presentationControllerDidDismiss?(presentationController) } }
まとめ
今回は、iOS13以降で、モーダル表示の変更についての記事を書きました。
iOS12からiOS13への変更で大きく変わったのは、ダークモード対応と、このモーダル表示です。
ダークモード対応についての記事も以前に書いてあるので、みてみてください。
【Swift5/Xcode】縦画面固定、ダークモード無効化、iPadでiPhone表示。毎回忘れるので、記事に残しておきます。