俺のアプリがこんなにダークなわけがない

タイトルの言い回しがもう古いかもしれませんが、最近の流行りがわからないのです・・・

# こんなアプリを作ったよ

以前、[続：どこまでショボいアプリがAppleの審査に通るのか試してみた](https://qiita.com/megumu-u/items/29c28ed9b2b3830769f7)で作ったアプリをiOSのダークモードに対応してみました。
このアプリは5W1Hで予言を表示するというアプリでした。

このアプリを

　ライトモードなら白背景
　ダークモードなら黒背景

にしてみました。

**でも・・・ただ、それだけじゃつまらないよね・・・**

ということで、**ダークモードの時は「暗い奴」にすることにしました。**

え、意味がわからない？
つまりこういうことです。


<img width="286" alt="スクリーンショット 2019-12-13 0.07.23.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/201603/c3ecd6f0-05c7-dae0-1816-ed3b376a8b16.png">

これはライトモード。
色合いも美しく、シンプルで見とれてしまいますね。
内容もなんだかパリピな感じで明るい。

＃ちなみに色はmaterialize-cssのカラーパレットから選びました
＃CSSフレームワークのカラーパレットから選ぶと良い感じにしやすいです


さて、これをiPhoneをダークモードにして実行すると・・・

<img width="321" alt="スクリーンショット 2019-12-13 0.06.57.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/201603/7a137c50-633f-5aaf-1deb-1e399b1902c5.png">

**なんということでしょう！内容が陰湿になりました！**
見た目も中身もまさしくダークモードです！
OSのカラーモードでアプリの機能まで変えてしまうという、機能の趣旨を無視したアプリを作ることで世に一石を投じてみました。

動画で見るとこんな感じです。
ライトモードかダークモードかで言葉の辞書を変えてます。

![movie.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/201603/127f5539-6c3b-397d-d308-b68b960bbf0f.gif)


# こんな実装だよ

実はこの記事はXamarinのアドベントカレンダーに参加してるのでXamarinっぽいことも書きます。
ResouceDictionaryとDynamicResourceを使って、モードに応じて色を切り替えてます。

まずダークモードの判定は、Xamarin.iOS側に以下のような実装を書くことで取得できます。

````csharp
//iOS側の処理（DependencyServiceで取得できるようにする）

        public bool IsDarkMode()
        {
            if (UIDevice.CurrentDevice.CheckSystemVersion(13, 0))
            {
                if (new UIViewController().TraitCollection.UserInterfaceStyle == UIUserInterfaceStyle.Dark)
                {
                    return true;
                }
            }
            return false;
        }
````

これをアプリの起動と再開時に取得します。

````csharp
//App.xaml.cs

        protected override void OnStart()
        {
            SetTheme();
        }

        protected override void OnResume()
        {
            SetTheme();
        }

        private void SetTheme()
        {
            //１回スレッドを切らないとレジューム時に値がちゃんと取れなかった
            Device.BeginInvokeOnMainThread(() =>
            {
                IsDark = DependencyService.Get<IDeviceService>().IsDarkMode();
                if (IsDark)
                {
                    Resources["Background"] = Color.FromHex("000000");
                    Resources["TextColor"] = Color.FromHex("FFFFFF");
                    Resources["Accent"] = Color.FromHex("FFFF00");
                }
                else
                {
                    Resources["Background"] = Color.FromHex("fafafa");
                    Resources["TextColor"] = Color.FromHex("424242");
                    Resources["Accent"] = Color.FromHex("1565c0");
                }
            });
        }
````

最後のResoucesについてはApp.xaml側に書いてます。

````xml
<?xml version="1.0" encoding="utf-8"?>
<Application xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="Glorious.App">
    <Application.Resources>
        <ResourceDictionary>
            <Color x:Key="Background">#000000</Color>
            <Color x:Key="TextColor">#FFFFFF</Color>
            <Color x:Key="Accent">#FFFF00</Color>
        </ResourceDictionary>
    </Application.Resources>
</Application>
````

このResourcesを画面側で以下のような感じで参照してます。

````xml
<Button Text="{Binding Predict.ButtonText}"
                    WidthRequest="260"
                    Clicked="Handle_Clicked"
                    HorizontalOptions="Center"
                    Margin="0,30,0,0"
                    FontSize="20"
                    TextColor="{DynamicResource TextColor}" ←ここ
                    BackgroundColor="{DynamicResource Background}" ←ここ
                    BorderColor="{DynamicResource TextColor}" ←ここ
                    BorderWidth="1"
                    Padding="5,0,5,0"></Button>
````

あとはダークモードかどうかで表示する言葉の辞書を切り替えていました。

# まとめ

以上、ダークモードとは何なのかを履き違えたアプリを作ってみました。

今回の内容とは全く関係ないですが、単純なアプリでも良いので1個作っておくと、こんな感じでちょっとした調査に使いまわせて良いですよ。