【iOS】一つのアプリで複数種類のウィジェットを選択できるようにする

2023.03.28

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

多機能のアプリでは、ウィジェットもそのアプリに合わせて様々な機能のものを提供したいと思うからも知れません。私自身も様々なウィジェットを提供したいと思ったので、その方法を調べてみました。

はじめに

今回は、ウィジェット導入については過去の記事で記載しましたのでウィジェットの基本的な説明を省略しております。

導入については、下記の記事や下記記事内の参照記事をみていただければとも思います。

【iOS】ウィジェットとCoreDataを連携する入門

環境

  • Xcode 14.2
  • iOS 16.2

作ったもの

multiple widget demo

複数種類のウィジェットを選択できるようにする

至ってシンプルで、Widget Extensionを追加すると作成される@mainが付与されたWidgetBundleプロトコルに準拠した構造体に、追加したいウィジェットを追加するだけです。

import WidgetKit
import SwiftUI

@main
struct MultipleWidgetBundle: WidgetBundle {
    var body: some Widget {
        // ここに追加する
        SampleWidget()
    }
}

Widget

例として、ウィジェットを複数作成しました。

struct GoodMorningWidget: Widget {

    let kind: String = "good morning"

    var body: some WidgetConfiguration {
        StaticConfiguration(kind: kind, provider: Provider()) { _ in
            GreetingWidgetEntryView(text: "おはよう")
        }
        .configurationDisplayName("朝の挨拶")
        .description("朝の挨拶を忘れないように貼っておこう")
    }
}

struct HelloWidget: Widget {

    let kind: String = "hello"

    var body: some WidgetConfiguration {
        StaticConfiguration(kind: kind, provider: Provider()) { _ in
            GreetingWidgetEntryView(text: "こんにちわ")
        }
        .configurationDisplayName("昼の挨拶")
        .description("昼の挨拶を忘れないように貼っておこう")
    }
}

struct GoodbyeWidget: Widget {

    let kind: String = "goodbye"

    var body: some WidgetConfiguration {
        StaticConfiguration(kind: kind, provider: Provider()) { _ in
            GreetingWidgetEntryView(text: "さよなら")
        }
        .configurationDisplayName("別れの挨拶")
        .description("さよならは別れの言葉じゃないよ")
    }
}

WidgetBundle

import WidgetKit
import SwiftUI

@main
struct MultipleWidgetBundle: WidgetBundle {
    var body: some Widget {
        GoodMorningWidget()
        HelloWidget()
        GoodbyeWidget()
    }
}

このようにすることでウィジェット選択時に複数のウィジェットから選べるようになります。

補足

Appleのサンプルでは、下記のように複数ウィジェット対応の場合は@WidgetBundleBuilderを付与していたのですが、こちらを付けなくても今の所正常に動作しました。

@main
struct GameWidgets: WidgetBundle {
    @WidgetBundleBuilder
    var body: some Widget {
        GameStatusWidget()
        CharacterDetailWidget()
        LeaderboardWidget()
    }
}

今後、こちらに関して追加の情報を取得したら追記したいと思います。

おわりに

複数のウィジェットを選択できるようにするのはとても簡単でした。 アプリの内容に合わせて、複数のウィジェットを作成し、その中からユーザー自身に合ったウィジェットを選べれるようになるとユーザー体験が向上するかも知れませんね。

引き続きウィジェットを楽しんでいきたいと思います。

参考