【概要】

iOS14 からホーム画面にWidgetを追加できるようになりました。

そのため、様々なアプリが対応することになり、一度に表示されるアプリの数が減る可能性があります。結果として、Widgetの対応を求められることが多くなる可能性があります。

すでにいくつかのサイトで紹介され初めてはいますが、初歩編として紹介します。

ー参考公式ページ

https://developer.apple.com/documentation/widgetkit/creating-a-widget-extension

 

【Widgetの追加手順(最低限)】

ただ、Widgetを追加するだけならすぐ終わります。

 

1. File → New → Targetを選択

 

2. Widget を選択

  
 

3. オプションの選択

※ Include Configuration Intentを選ぶとユーザー設定可能なプロパティを持つwidgetが作成されます。さっとためすなら、チェックを外します。

 

4.以下の感じで追加されます。

 

これで一旦実行します!すると、以下の感じでWidgetになります!さくっとできますね!

 

以下に、いくつか補足します。

 

【各サイズの設定】

1. Widget にて、supportedFamilies を追加し、サポートするサイズを指定します。

以下の例では、Small/Medium/Largeのすべてを指定しています。

@main
struct SimpleWidExt: Widget {
 let kind: String = "SimpleWidExt"

 var body: some WidgetConfiguration {
 StaticConfiguration(kind: kind, provider: Provider()) { entry in
  SimpleWidExtEntryView(entry: entry)
 }
 .configurationDisplayName("My Widget")
 .description("This is an example widget.")
 .supportedFamilies([.systemSmall, .systemMedium, .systemLarge])
 }
}

2. Viewで各サイズの表示を設定

struct SimpleWidExtEntryView : View {
 @Environment(\.widgetFamily) var family: WidgetFamily

 var entry: Provider.Entry

 @ViewBuilder
 var body: some View {
  switch family {
   case .systemSmall:
     HStack {
     Image("xxxx")
       .resizable()
       .frame(width: 50, height: 50, alignment: .center)
   Text(entry.date, style: .time)
   }
   case .systemMedium:
     HStack {
       Text("Medium")
       Text(entry.date, style: .time)
     }
   case .systemLarge:
     HStack {
       Text("Large")
       Text(entry.date, style: .time)
     }
   default: Text("Default")
   }
 }
}

3. 以下の感じになります。

 

※サイズは、ウィジェットの追加をするときに選択ができます。以下のようにウィジェット追加時にスワイプで各サイズが選べます。

 

【リロードのタイミング】

timelineにて、リロードのタイミングを指定することができます。

以下の例では15分毎にリロードするポリシーを設定しています。

public func timeline(with context: Context, completion: @escaping (Timeline<Entry>) -> ()) {
 let date = Date()
 let entry = SimpleEntry(date: date)
 let nextUpdateDate = Calendar.current.date(byAdding: .minute, value: 15, to: date)!

 let timeline = Timeline(
  entries:[entry],
  policy: .after(nextUpdateDate)
 )
 completion(timeline)
}

<

p data-renderer-start-pos=”2599″>※公式ページで上記のコードが紹介されているのですが、いくつかのサイトをみると、.after が意図した感じで動かないようです。。。(私の環境でもずっと更新され続けるとかがおきました。本リリースで修正期待しましょう)

 

【アプリ側から強制的にリロード】

アプリが通知を受けて更新するなどといった場合など、アプリ側からWidgetを更新することが可能です。
以下を呼び出すことで、アプリのWidgetすべてをリロードさせることが可能です。

WidgetCenter.shared.reloadAllTimelines()

参考ページ: https://developer.apple.com/documentation/widgetkit/widgetcenter