見出し画像

Now in REALITY Tech #20 REALITY iOSのダークモード対応について

今週の「Now in REALITY Tech」は、最近サポートされたダークモードの対応方法やサポート前後での課題についてiOSチームからお送りします。

ダークモード対応の背景

REALITY Androidでは既にダークテーマをサポートしていましたが、REALITY iOSではまだダークモードに対応出来ていなかったことから、定性的なユーザ体験の向上を目的として、REALITY iOSアプリでも対応することとなりました。
ダークモード対応して目に優しくしていきたい!!

ダークモード対応における課題


1. ダークモードのデザイン、カラーアセットがfigmaにない

Androidでダークテーマをサポートをしていましたが、figmaではライトモードを想定としたデザインが組まれており、ダークモード時のデザインは考慮された状態ではありませんでした。
また、ライト・ダークモード毎のテキストや背景色などのカラーアセットがない状態であったため、Androidでのダークテーマをベースにデザイナーとカラーアセットを定義しました。

スクリーンショット 2021-10-27 17.56.14

2. 異なるモジュール間で共通のカラーアセットを使用したい

定義したカラーアセットをアプリターゲットだけでなく異なるモジュール間で使用することを想定し、カラーアセットを管理するEmbedded Frameworkを作成することで解決しました。カラーアセットを持つEmbedded Frameworkを使用した具体的な実装方法は後述します。
また、モジュール化の対応についてはGree Tech Conferenceにて詳細に解説しているのでこちらを参照ください。

REALITY iOSアプリを支える開発効率化

ダークモード対応の実装

カラーアセットの定義やEmbedded Frameworkへの切り出しが完了すれば、あとはUIコンポーネントに対してカラーを設定するだけです。
カラーアセットを管理するEmbedded FrameworkではR.swiftを用いてxcassetsへの参照を型安全かつSwiftyに実装出来るようにしています。
注意点としては、カラーアセットをEmbedded Frameworkに切り出したことで、storyboardやXIBから定義した色を設定できるが、設定した色をどのモジュールから参照するか明示的に指定出来ないためランタイムでは参照出来ません。
そのため、実装はコードから指定する必要があり具体的には下記のようになります。

// アプリターゲットでもR.swiftを使用していることから、
// RealityResources.Rのtypealiasを下記のように設定しています
// public typealias Assets = RealityResources.R

import RealityResources

class UserCell: UITableViewCell {
   @IBOutlet weak var nameLabel: UILabel!
       didSet {
           nameLabel.textColor = Assets.color.textPrimary()
       }
   }
   @IBOutlet weak var iconView: UIImageView! {
       didSet {
           iconView.tintColor = Assets.color.icon()
       }
   }

   .
   .
   .
}

アイコンの色設定に関しては、上記のサンプルコードのようにコードで指定することも可能ですが、アプリ内で保持するアイコンであれば下記のようにダークモード用の画像を用意することで、ユーザのAppearanceの設定によって動的に出し分けすることが可能です。

スクリーンショット 2021-10-27 17.58.42

対応して見えてきた課題

1. ダークモード対応の実装を簡易にしたい

1つの画面をダークモード対応する場合 UIViewの背景色やテキストカラー、アイコンカラーなど、考慮する点が多いためダークモード対応前後で開発コストが上がります。
対応時には、ダークモード対応の簡易化を目的としてUIViewやUIViewControllerの背景色の設定をViewDidLoadをMethod Swizzlingするなどして設定することを試みましたが断念しました。
理由としては、UIKitや依存ライブラリにおいてUIView、UIViewControllerを継承したclassを保持している場合に意図しない挙動となる可能性があるためです。
例えば、UIKitのopenでない UIEditingOverlayViewController に背景色がセットされるケースがあり、愚直に設定することを選択しました。

2. ダークモード対応漏れを防ぎたい 

1の課題とも共通しますが、開発者がUIを実装する際にライトモード、ダークモードの両方でUIを確認することは開発コストが上がることに加え、人的ミスが発生するリスクがあります。
この問題への対処方法の一つとして、UITestを導入しスクリーンショットテストでUIの見栄えを自動的に把握することがありますが、弊社ではまだ導入しきれていない部分なので、今後の課題となっています。

3. ネットワーク経由で表示する画像の表示

今までライトモードを前提としてアプリに表示していた画像が、ダークモードになると可視性が低くなったり、背景色と画像の配色がマッチしない状態で表示されることがありました。
サービス提供側で保持する画像については、画像の差し替えや色設定により見栄えを変えることが出来ますが、ユーザがアップロードする画像についてはサービス提供側はアンコントローラブルであるため、サービスによっては「お知らせ」などでユーザにダークモード対応したことを共有することが重要となってきます。

まとめ

今回はiOSでサポートしたダークモードの対応について紹介しました。

ダークモードの対応により、ユーザの好みに合わせた見栄えを提供することが可能となったため、より良いユーザ体験を提供できたらと思っています。

REALITY では一緒に開発してくれるメンバーを大募集しています! まずは気軽にカジュアル面談も受け付けていますので、お気軽にお申し込みください!