文系プログラマの勉強ノート

スマホアプリ開発やデザインなどについて勉強したことをまとめています

【iOS13】Dark Mode対応

f:id:an3714106:20191021230627p:plain:w400

iOS13からDark Modeが使えるようになりました。

Xcode11(iOS13 SDK)でビルドされたアプリは自動的にDark Modeが有効になるので、
「うちのアプリはDark Mode対応しなくていいや」という訳にもいきません。
(2019年10月時点で必須ではありませんが、将来的に必須になりそうです)

ということでDark Mode対応について勉強したことをまとめておきます。


Dark Modeにするとどうなるか

まずDark Modeにしたとき自分のアプリがどういう外観になるのか確認しておきます。
iOSの 設定 > 画面表示と明るさ から変更できます。
(シミュレータの場合は設定 > デベロッパ から)

Dark Modeに対応できているアプリは暗色系の配色になります。
(以下の例はデフォルトのUIコントロールをそのまま使いました)

f:id:an3714106:20191026234724p:plain:w400

一方Dark Modeに対応できていないアプリ、つまりは従来の色指定方法で色をカスタマイズしているアプリは Light Modeと外観が変わりません。

f:id:an3714106:20191026234749p:plain:w400

実際にはパーツによって色が変わる部分と変わらない部分が入り混じっている状態が多いと思います。
ブランドカラーなどDark Modeでも共通の色を使いたい部分には従来の色指定を使い、
Modeによって変えたい部分は色指定を修正します。


システム定義のカラーを使う

iOS13以降で使えるDark Mode対応のシステム定義カラーが用意されています。
これらを使うとModeの切り替わりに合わせて自動的に色が変化し、かつiOSらしい配色になります。

f:id:an3714106:20191027003803p:plain:w200 f:id:an3714106:20191027003748p:plain:w200

システム定義カラーには、例えば「label」「systemBackground」など用途に応じた色や、
「systemBlue」「systemGray」など色名で定義された色があります。
ちなみに用途別の色(UI Element Colors)や「system」と付くのがDark Mode対応(Adaptable)な色で、
「black」などiOS12以前から使っていたシステム定義カラーは静的な色として引き続き使えます。

使い方は従来と同じです。

 view.backgroundColor = UIColor.systemBackground

Dark Mode対応のシステム定義カラーの詳細は別記事にまとめましたので、そちらをご覧ください。

an.hatenablog.jp


Dark Mode対応カラーを自作する

システム定義カラーにぴったりの色がない場合は自作もできます。
Asset Catalogを使う方法とコード上で定義する方法があります。

Asset CatalogでDark Mode対応カラーを定義する

f:id:an3714106:20191027134349p:plain

Asset Catalogの + ボタンから Color Set を作成します。
Dark Mode対応の色を定義したい場合は、Attributes Inspector の Appearance で「Any, Dark」か「Any, Light, Dark」を選び、それぞれの色を指定します。

使い方はImage Setと同じで、名前で指定します。

 view.backgroundColor = UIColor(named: "Color_Background")

ちなみに、同じやり方で画像もLight Mode / Dark Modeで自動的に切り替えられます。

f:id:an3714106:20191027141501p:plain

コード上でDark Mode対応カラーを定義する

動的に色が決まる場合はAsset Catalogが使えないのでこちらの方法になります。

「UITraitCollection.userInterfaceStyle」を使うと今がLight ModeなのかDark Modeなのかを判断できます。
このUITraitCollectionを引数にしてUIColorを作成します。

static var background: UIColor {
    if #available(iOS 13, *) {
        return UIColor { (traitCollection) -> UIColor in
            if traitCollection.userInterfaceStyle == .dark {
                // Dark Mode
                return UIColor(red: 0, green: 0, blue: 0, alpha: 1)
            } else {
                // Light Mode
                return UIColor(red: 1, green: 1, blue: 1, alpha: 1)
            }
        }
    }
    // iOS12以前
    return UIColor(red: 1, green: 1, blue: 1, alpha: 1)
}

これらの方法で色を指定すればLight Mode / Dark Modeの切り替えに合わせて自動的に切り替わるため、自分で画面を更新する必要はありません。


こんな感じでオリジナルのDark Modeテーマができます。

f:id:an3714106:20191028221653p:plain:w400


【番外編】アプリ全体 or 部分的にDark Modeを無効にする方法

とはいえ、すぐには対応できないので一時的にDark Modeを無効にしたい場合もあります。

アプリ全体で無効にするためには、Info.plistにKeyが「UIUserInterfaceStyle」、Valueが「Light」の項目を追加します。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    (中略)
    <key>UIUserInterfaceStyle</key>
    <string>Light</string>
</dict>
</plist>

または、印刷プレビュー画面など常にLightモードでの外観が適切な画面もあるでしょう。
その場合は画面の初期化時に「overrideUserInterfaceStyle」プロパティを「.light」に指定します。

override func viewDidLoad() {
    super.viewDidLoad()

    // この画面だけLightモード固定にする
    self.overrideUserInterfaceStyle = .light
}


参考サイト

developer.apple.com

qiita.com

qiita.com