NSAppearance.current の役割
- Apple
- 開発
なぜか天気予報の全国図で一番気温が高い日が多く 39℃ が当然のように何日も続いていた名古屋にもやっと秋が来た1。秋といえば Apple プラットフォーム開発者が忙しい季節。例によって iOS 12 の話は置いておくとして、ここで取り上げる話題はもちろん macOS Mojave についてだ。
Mojave といえばやはり目玉はダークモード2。WWDC 2018 の関連セッションビデオを見ると NSColor
に追加されたシステムカラーの説明に重きが置かれている。
ユーザがいつでもモードを変更できるためこれらのカラーはそれに応じてダイナミックに変化するようになっていて、例えば NSColor.controlBackgroundColor
はダークモードで描画すると暗いグレー、そうでなければホワイトとして描画される。
でもどうやって判別しているのか。システム全体が非ダークモード(ライトモード?)であってもダークなウインドウを混ぜることができるし、ライトなウインドウの中に一部だけダークなビューを混ぜることもできてしまう。そのためシステムの設定を取得しても意味がない。
そこで使用されているのが NSAppearance
にある current
というクラスプロパティ。NSView
は draw(_:)
とか updateLayer()
が呼び出される直前にこれをセットしているため NSColor
のシステムカラーは描画相手のことを知らないのに自身の値を変化させることができているようだ。
実験
このプロパティは自力でセットすることも可能なようなので実験してみよう。
NSAppearance.current
の内容に応じてカラーの RGB 値が異なることがわかる。
アプリケーション開発者は通常はダイナミックなカラーを使用するだけでよく、NSView
自体も effectiveAppearance
というプロパティを持っているため NSAppearance.current
を触る場面はほとんど存在しないように見えるけど、「drawingHandler
で描画する NSImage
」みたいに相手先が誰であるか知らないオブジェクトで描画時点のダークモードの有効/無効に応じて独自の変化をさせたい場合には使えそうなプロパティだ。
また、通常の描画でないタイミングでイメージを生成してビットマップとしてキャッシュをしておきたい場合でもこれをセットすれば任意のアピアランスに応じたカラーを使用できそう。
お片づけ
NSGraphicsContext
などと同様、自力でセットする場合は念のため最後にもとの値に戻るようにするのをお忘れなく。こういうお片づけ処理は Swift の defer {}
を使うと最初にまとめて書けてすっきりだ。
Share
リンクも共有もお気軽に。記事を書くモチベーションの向上に役立てます。