【Xcode】 ダークモード対応

iOS 13に正式に対応したアプリ開発環境はXcode 11。
Xcode 11はmacOS Catalinaでなければ動かないと思っていたので、未だmacOS Catalinaの正式版公開日が決まっていない現在、まだ待ちなのだと思ってぼーっとしていました。
実際にはXcode 11はiOS 13公開日の翌日にダウンロード可能になっていたので、iOSアプリ開発を再開しなくてはいけません。

しばらく休止していたアプリ開発を再開するにあたって、今日はダークモードへの対応についてAppleのDocumentationを読んでいました。

配色については、iOSの外観モードに応じて動的に色を変更する機能が新たに実装され、例えば従来は「UIColor.red」としていたところを「UIColor.systemRed」のように指定すれば、ライトモードのときは白地に映える赤に、ダークモードのときは黒地に映える赤になるようです。(これを「semantic colors」という)

画像についてはAsset Catalogを利用すれば、同様に外観モードに応じて動的に画像を変更できるようです。

ダークモード対応、簡単だね。よかったよかった。
というわけにはいかなくて、これが。

UIColorはsemantic colorsで手軽にダークモード対応できるのですが、CGColorにはsemantic colorsという機能がありません。
だから外観モードに応じて、そして外観モードの変更に応じて、CGColorを変更する機能を自前で実装しなければいけない。

画像については問題なさそうですが、私はAsset Catalogを使うことに肯定的ではありません。
Asset Catalogは複数人でアプリ開発を行うとき、特にその規模が大きいときや役割分担が明確なときには効果的だと思いますが、私は独りなのでAsset Catalogの恩恵は小さいと思います。
そして画像ファイルというリソースの管理はファイラーで行いたい。Xcodeで管理したくはないのです。

Asset Catalogは私の好みの問題といえますが、CGColorの問題があるので何れにせよダークモードに対応する処理は自前で実装しなければならないというのが、今のところの私の結論です。
だからUIColorは従来どおり私が指定したい色を指定しますし、画像ファイルはファイラーで管理します。
それらをライトモード用とダークモード用別個に作り、好きなタイミングで変更する機能を作ることにします。

既存のアプリをダークモードに対応させる場合はviewDidLoad()に記していたUIViewの定義から色に関する部分を分離してviewWillLayoutSubviews()などに記述します。
また、例えばボタンを押すと画像を変更するような処理を作っているならば、そのような箇所からも色に関する部分を分離する必要があります。
うーん、何だか取りこぼしが発生してしまいそうです。
やる前から弱気になってしまいますが、やらなければいけません。
ダークモードに対応しないという選択肢もありますが、そのような逃避は自己満足の観点からあり得ないことです。
既存のアプリをダークモードに対応させるという場合、見直すべきUIViewを取りこぼしても動作には問題を生じないので、コーディングのときに全てのUIViewを漏れなく網羅するということが重要になります。
できることは、集中力を切らさないことくらいしかありません。
たっっっぷり休憩を取りながら、地道に進めることにしましょう。