Widgetの準備をする
Widgetを作成したいプロジェクトをXcodeから開く。
主なファイルの役割は以下の通りです
- Widget
- Widgetの見た目などを設定する
- WidgetBundle
- 異なる種類のWidgetを扱える
- WidgetLiveActivity
- Live Activityを使用する時に使うファイル
コードの編集
1種類しかWidgetを使わないのであれば、WidgetBundleは必要ないので、全てコメントアウトします。
Widget.swift
Widgetファイルを編集していく
まず扱うデータを定義する。
デフォルトの状態で
struct SimpleEntry: TimelineEntry {
let date: Date
let emoji: String
}
となっている場所がある。
ここではWidgetで扱うデータの型を指定する。
ここで注意するのは、
let date: Date
は必ず必要だということ。
例えばStringの配列を扱いたいのであれば
struct SimpleEntry: TimelineEntry {
let date: Date
let data: [String]
}
と記述する。
データを取得する
Widgetで扱うデータを取得するのは、一番上にあるProvider内で行います。
まず、データを取得する前に仮置きするデータをあらかじめ決めておきます。
*すぐに表示できるように、データはここ以外の場所に置かないようにします。(データベースは使わない)
struct Provider: TimelineProvider {
//仮置きするデータを定義する関数
func placeholder(in context: Context) -> SimpleEntry {
//以下のように書いて定義する
SimpleEntry(date: Date(), data: ["データ取得中"])
}
}
このように、必ずSimpleEntry(先ほど定義したデータ型)を返すようにする。
そして、ホーム画面に追加するWidgetを選ぶ画面で表示するデータもあらかじめ定義します。
*すぐに表示できるように、データはここ以外の場所に置かないようにします。(データベースは使わない)
struct Provider: TimelineProvider {
func placeholder(in context: Context) -> SimpleEntry {
...
}
//仮置きするデータを定義する関数
func func getSnapshot(in context: Context, completion: @escaping (SimpleEntry) -> ()) { {
//以下のように書いて定義する
let entry = SimpleEntry(date: Date(), data: ["サンプルデータ"])
complpetion(entry)
}
}
completionの()の中に返したいデータを指定します。
ここでも必ずSimpleEntryを返す
最後に本当に表示したいデータを定義します。
struct Provider: TimelineProvider {
func placeholder(in context: Context) -> SimpleEntry {
...
}
func getSnapshot(in context: Context, completion: @escaping (SimpleEntry) -> ()) { {
...
}
//本当に表示したいデータを定義する
func getTimeline(in context: Context, completion: @escaping (Timeline<Entry>) -> ()) {
//以下のように書いて定義する
let entry = SimpleEntry(date: Date(), data: ["サンプルデータ"])
completion(Timeline(entries: [entry], policy: .atEnd))
}
}
ここで注意するのは、SimpleEntryの配列をentriesに指定することで、Timelineという型を返す。
また、UserDefaultsを使うときはちょっとした工夫が必要だが、以下に書いてある。
またアプリでの変更をWidgetに即時反映させたい時は、UserDefaults操作の直後に
WidgetCenter.shared.reloadAllTimelines()
を記述する。
見た目を作る
Widgetは必ず、SwiftUIというフレームワークを使用して見た目を作る。
WidgetEntryViewというところに書いていく。
以下に例を示しておく。
struct WidgetEntryView : View {
//扱いたいデータが詰まっている変数
var entry: Provider.Entry
//この中に見た目をかく
var body: some View {
//ForEachは、tableViewみたいな、同じ見た目を複数作成するときに使う
//entry.dataのところは配列型、id: \.selfはとりあえずそのまま書いておけばOK
//dataは、entry.dataで取り出したデータのうちの、一つの要素のこと
ForEach(entry.data, id: \.self) { data in
//縦に並べるものをこの中にかく。横に並べる時はHStack、重ねたい時はZStack。
VStack {
//Textは文字を表示する。()の中に表示したい文字列を指定する。
//.を使って、見た目を整える。
Text(data[0])
.frame(maxWidth: .infinity, alignment: .leading)
Text(data[1])
.foregroundStyle(.secondary)
.font(.caption)
.frame(maxWidth: .infinity,alignment: .leading)
.padding(.bottom, 2)
}
}
}
}
これでWidgetを最低限表示できるようになりました!
お疲れ様でした!