ちょっとマニアックな情報ですが、ドキュメントのどこにも書かれていないとっておきのネタです。
Action Extension、またはShare Extensionを開発していて、UINavigationBarを利用しているという方はぜひご覧ください。
この記事は Cocoa Advent Calendar 2016 6日目の記事です。昨日の記事はnaochi___さんの[iOS] Xibを使って自前のダイアログを作るでした。
この記事では、id:kaniza さんの4日目の記事 第 70 回 Cocoa 勉強会関西に行ってきた - kanizaのブログ で触れられている、 第70回 Cocoa勉強会関西 で私が発表した内容について書きます。
"App Extension 上で UINavigationBar.appearance() が HostApp の影響を受ける問題" とは?
このような画面のAction Extensionを作成したとします。以降このTargetを"Action" Extensionと呼びます。
NavigationBarのBar Tintがオレンジに、DoneボタンのTintが白になっています。
予定では、このエクステンションを起動するとこのような画面になるはずです。ここで見えているオレンジ色のNavigationBarがこの問題の主役です。
実際に起動するとどうなるでしょうか。Safari上で試してみます。共有ボタンから開いたアクションシートで今作成した "Action" Extensionを開きます。すると設定通りの画面が表示されます。
同じことをPocketというアプリの上でやってみます。共有ボタンから "次を使用して共有:" を選んで開いたアクションシートで、"Action" Extensionを開きます。そうすると今度は、NavigationBarが意図した色になっていません。
これが "AppExtension上でUINavigationBar.appearance()がHostAppの影響を受ける問題" です。
何が原因か
原因は UINavigationBar.appearance() 周りにあります。
Pocket上でNavigationBarが白くなってしまったのは、Pocketが自身のアプリ上のNavigationBarの見た目をカスタマイズするために、UINavigationBar.appearance().barTintColorを白に設定しているため、と考えられます。
試しにUINavigationBar.appearance().barTintColorを赤にするアプリを自作し、そのアプリからExtensionを起動すると、今度はNavigationBarが赤くなります。
UIAppearanceの設定は、そのアプリ上で利用するApp Extensionにまで影響を及ぼすのです。
この問題にどうやって対応するのか
この問題を防ぐ方法は、密かにiOS10から利用できるようになっています。App ExtensionのInfo.plistに設定することが出来る NSExtensionOverridesHostUIAppearance
キーです。
NSExtensionのDictionaryの中にBooleanでYESを設定します。
これを設定した "Action" Extensionをもう一度Pocket上で起動してみます。すると、今度は意図した通りのカラーでNavigationBarが表示されました。
この NSExtensionOverridesHostUIAppearance
については、ドキュメントには書かれていません。しかしiOS10から機能します。また、このキーを利用してもAppStoreの審査で問題になることはありません。
UINavigationBar.appearance()がHostAppの影響を受ける問題はShare Extensionでも発生します。Extension上でUINavigationBarを利用している場合は、Info.plistに NSExtensionOverridesHostUIAppearance
を追加しておくと良いと思います。
参考
ここのIssueでも言及されています。調査中ステータスのままですが。
インターネット上で NSExtensionOverridesHostUIAppearance
に言及しているサイトはこの記事が2番目のはず...