12
10

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

iOS13のモーダルはFullscreenもいいけどCurrentContextも検討してみて

Last updated at Posted at 2019-10-20

iOS13からモーダルを表示するときはセミモーダルがデフォルトの挙動となりました。
スクリーンショット 2019-10-20 20.02.06.png
完全なフルスクリーンではなく後ろのViewが少し見えるようなデザインで、下にスワイプで元のViewに戻ることができます。

これをされると困るデザインがあります。例えばログイン後に表示されるViewはセミモーダルではなくフルスクリーンで表示したいでしょう。

StoryboardからPresentationをFullscreenにすることで次のモーダルを完全なフルスクリーン状態で遷移できます。
スクリーンショット 2019-10-20 20.06.52.png

Swiftの場合はこうします。

let vc = ViewController()
vc.modalPresentationStyle = .fullScreen
present(vc, animated: true)

スクリーンショット 2019-10-20 20.09.27.png
この状態であればスワイプで戻ることもできません。
ここまでであればあまり問題はなさそうに見えます。

さらにModalで遷移したいとき

ここからさらにモーダルを表示したいとします。このときはセミモーダルのほうが利便性があがるので普通の遷移にします。
するとどうでしょう。

スクリーンショット 2019-10-20 20.12.18.png
なんと後ろのViewが下がらないままセミモーダルが出てしまいました。

iOS13においてfullscrrenでモーダル表示したものはずっとfullscreenの状態を維持するのでこのような動きになるようです。
でもこれじゃかっこよくない!下がってほしい!というときはCurrent Contextを使ってみます。

先ほどのFullscrrenからCurrent Contextに変更します。するとStoryboard上では灰色はフルスクリーンで、その次のモーダルでは灰色Viewが下にずれているのが確認できます。
(よく見ると上のStoryboardでもFullscreen選択時のモーダルの見え方はシミュレートされていましたね)
スクリーンショット 2019-10-20 20.15.10.png

ではこれで解決!かと思いきや実際実行してみると・・・

スクリーンショット 2019-10-20 20.17.49.png
なんと今度はステータスバーが全く見えなくなってしまいました。

CurrentContext時にStatusBarを見えるようにする

これは推測ですが、CurrentContextによって諸々の状態を参照する先が灰色のViewになっているのだと思われます。灰色Viewの時点ではステータスバーは黒色テキストなので、モーダル遷移後も灰色Viewからステータスバーの情報を取得していると考えると、黒の背景に黒のテキストとなってしまい見えなくなってしまったものと考えられます。

これを回避するにはViewController毎にステータスバーの色は何色にすべきかという情報を設定します。

灰色のViewControllerにpreferredStatusBarStyleプロパティをオーバーライドします。

class ViewController: UIViewController {
    override var preferredStatusBarStyle: UIStatusBarStyle {
        if presentedViewController != nil {
            return .lightContent
        } else {
            return super.preferredStatusBarStyle
        }
    }
}

presentedViewControllerは現在のViewController(灰色)からみてさらにモーダル表示しているViewControllerがあればそのViewControllerが、なければnilが返ってきます。
つまりpresentedViewControllerがnilでないなら何かしらモーダルを表示しているということです。
このときはステータスバーを白とし、それ以外はデフォルトの挙動としました。
ここを拡張することでもう少し細かな要望にも応えることができます。例えば次のModalもフルスクリーンだったらデフォルト挙動にするとかですね。

青色のViewControllerのpreferredStatusBarStyleは参照されませんでした。これもCurrentContextが影響していると考えられます。

これでめでたくセミモーダル時にステータスバーが白になりました。
スクリーンショット 2019-10-20 20.22.55.png

12
10
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
12
10

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?