【watchOS】WidgetKitでコンプリケーションを作成する

2023/05/23に公開

Apple Watchの文字盤にコンテンツを表示したり、Appを起動するためのショートカットを表示することができる領域のことをコンプリケーションと呼びます。

以前まではClockKitを使用してコンプリケーションを開発していましたが、watchOS 9以降では、WidgetKitを使用してコンプリケーションを作成することができるようになりました。
これによりホーム画面ウィジェットや、ロック画面ウィジェットに似た実装方法で、コンプリケーションを作成することができます。

本記事ではWidgetKitを使用して、コンプリケーションを作成する方法について書きます。
WidgetKitの基本事項に関しては、以下の記事にまとめています。まだWidgetKitに触れたことがない方は、必要に応じて以下の記事をご参照ください。

【iOS】WidgetKit 入門

コンプリケーションの種類

コンプリケーションの種類は4つです。

  • accessoryCircular
  • accessoryCorner
  • accessoryRectangular
  • accessoryInline

この種類のことをWidgetKitでは、WidgetFamily と呼びます。

WidgetFamily によって表示領域や形状が大きく異なるので、表示したいコンテンツはどのWidgetFamily が適しているかを吟味してから実装する必要があります。

コンプリケーション開発の準備

watchOS AppのXcodeプロジェクトの作成

今回の開発ではiOS Appは不要なので、watchOS Appのみの新規プロジェクトを新規作成します。

Widget Extensionターゲットの追加

プロジェクトを作成した後に、WidgetKit Extansionターゲットを追加します。サンプルプロジェクトでは、ターゲット名を"SampleComplication"としました。

コンプリケーションの実装

サポートするコンプリケーションの定義

どのWidgetFamily をサポートするかを定義します。StaticConfigurationのイニシャライザに渡したクロージャ内のエントリView(サンプルプロジェクトではSampleComplicationEntryView)に対して以下のように記述します。

CornerComplication()CircularComplication()InlineComplication()RectangularComplication() はコンプリケーションに表示するViewです。現段階では未実装なのでエラーが表示されますが、気にしないで読み進めてください。

@Environment(\.widgetFamily) で、WidgetKitが要求しているWidgetFamily を取得することができます。上記コードでは、要求されているWidgetFamily に応じて、表示するコンプリケーションViewを切り替えています。

コンプリケーションView

それではコンプリケーションに表示するViewを実装しましょう。
以下のようにViewプロトコルに準拠した構造体を4つ記述してください。

ビルド結果

プロジェクトをビルドしてみましょう。


文字盤をロングタップして文字盤の変更画面を表示し、文字盤の編集画面でコンプリケーションを変更することができます。

コンプリケーションのデザイン

widgetLabel モディファイア

accessoryCorner のViewは円形に切り取られて表示されるため、テキストやゲージといった横長いUIパーツの表示には向いていません。例えば、accessoryCorner 内のテキストは表示切れを起こしています。

accessoryCorner でテキストやゲージといった横長いUIパーツを表示させる時は、widgetLabel モディファイアを使用します。

文字盤の外側に沿って、テキストを表示させることができました。

widgetLabel モディファイアでゲージを表示することもできます。

また、widgetLabel モディファイアは、accessoryCircular でも使用することができます。"インフォグラム"の文字盤には、内側に4つの円形コンプリケーションが搭載されています。

文字盤内側の4つの円形の中で、中央上部のコンプリケーションはwidgetLabel モディファイアで指定したコンテンツを表示することができます。

文字盤内側に4つの円形コンプリケーションを搭載している全ての文字盤が、widgetLabel モディファイアで指定したコンテンツをサポートしているわけではありません。例えば、"メリディアン"の文字盤には内側に4つの円形コンプリケーションが搭載されていますが、中央上部のコンプリケーションはwidgetLabel モディファイアで指定したコンテンツを表示することができません。

このままではwidgetLabel モディファイアで指定したコンテンツが、重要なコンテンツだった場合、Appのユーザビリティを低下させる恐れがあります。そこで@Environment(\.showsWidgetLabel) を使用して、widgetLabel モディファイアで指定したコンテンツを表示させることができる文字盤かどうかを判定します。
判定結果によって、表示するコンプリケーションViewを切り替えることで、この問題を解決することができます。

widgetAccentable モディファイア

widgetLabel モディファイアを使用することで、コンプリケーションのアクセントカラー変更を反映させることができます。例えば、以下の様なaccessoryRectangular のコンプリケーションViewを作成します。

コンプリケーションのアクセントカラーを変更しても、作成したコンプリケーションView内のTextには、変更が反映されません。
上記コードのText("Location List") に、widgetAccentable モディファイアを付加します。

コンプリケーションのアクセントカラー変更が、Text("Location List") に反映されるようになりました。

おわりに

WidgetKitを触ったことがある方は、ホーム画面ウィジェットや、ロック画面ウィジェットを作成する方法とほとんど変わらないという感想を抱かれたのではないでしょうか。
本記事ではコンプリケーションに表示するコンテンツの更新方法について書きませんでしたが、タイムラインプロバイダを使用して、コンプリケーションに表示するコンテンツを更新することもできます。

参考資料

・Go further with Complications in WidgetKit
https://developer.apple.com/videos/play/wwdc2022/10051/
・Complications and widgets: Reloaded
https://developer.apple.com/videos/play/wwdc2022/10050/

Discussion