WWDC25 visionOS用Widgetについてのまとめ

2025年6月16日
visionOS / Widget / WWDC25 / WWDC / SwiftUI /

top

visionOS 26空間Widget(ウィジェット) がサポートされましたね! この記事では空間Widgetでできることをサンプルコードを交えて解説します。

空間Widgetとは

iOSやmacOS同様にWidgetKitで構築したWidgetをvisionOSにも表示できます。

visionOSが他OSと大きく違うのはWidgetを現実世界の机や壁に設置できるところです。 机の上など水平面に設置したWidgetは自動でユーザーのほうに向きます。

机の上に配置されたWidget
机の上に配置
壁に配置されたWidget
壁に設置

Widgetのサイズ

Widgetのサイズは以下5種類から選べます。

size

どのWidgetもユーザーが任意にリサイズ(縦横比は変わらず75%から125%の範囲内で)できます。

scale

どのサイズをサポートするかは従来のiOSなどのWidgetと同様にsupportedFamiliesモディファイアで指定できます。

.supportedFamilies(
    [.systemExtraLarge, .systemExtraLargePortrait]
)

素材

material

visionOSのWidgetは素材が Paper(紙) なのか Glass(ガラス) なのかを指定できます。

Paperは印刷物のようなリアルなあしらいになり、Glassなら前景と背景の間に深みが出ます。

glass_dark

PaperGlassで周辺環境の明るさによる見え方の違いも出てきます。

素材はwidgetTextureモディファイアで指定できます。

.widgetTexture(.paper)

マウントスタイル

elvated

マウントスタイルとして以下2つをユーザーが選択可能です。

壁面に設置する場合はどちらのスタイルも選べますが、机など水平面に設置する場合はElevatedのみです。そのため、マウントスタイルとしてRecessedしかサポートしていない場合、水平面に設置できなくなります。

デフォルトで両方のマウントスタイルをサポートしますが、必要ならsupportedMountingStylesモディファイアでどちらか片方のみに限定できます。

.supportedMountingStyles([.recessed])

距離によるUIの変更

proximity

visionOSのWidgetは他OSのWidgetと違い、現実世界に設置されるためユーザーからの距離が遠くなることもあります。

そのため、ユーザーからの距離を検知してUIを変更できます。 例えば、ユーザーが離れたら表示項目を減らしてより大きなフォントで表示するなどです。

距離が近い
.default 距離が近い
距離が遠い
.simplified 距離が遠い

距離による切り替えはlevelOfDetail environment variable により可能で、以下2種の値を検知できます。

@Environment(\.levelOfDetail) var levelOfDetail

var body: some View {
    VStack {
        if levelOfDetail == .simplified {
            SimpleView()
        } else {
            DefaultView()
        }
    }
}

レンダリングモード

setting

デフォルトではvisionOSのWidgetはフルカラーで表示されますが、ユーザーが特定の色でのアクセントモードやモノクロモードに変更もできます。

tint

具体的には以下3種のレンダリングモードがあります。

これらのモードへの対応はvisionOSが自動である程度やってくれますが、必要ならアプリごとにカスタマイズできます。

具体的にはwidgetRenderingMode environment variable により振り分けます。

アクセントモード(.accented)では、白や黒で強調表示させたいViewを.widgetAccentableモディファイアで明示できます。

@Environment(\.widgetRenderingMode) var widgetRenderingMode

var body: some View {
    ZStack {
       switch renderingMode {
        case .fullColor:
           Text("Full color")
        case .accented:
           ZStack {
               Circle(...)
               VStack {
                   Text("Accented")
                       .widgetAccentable()
                   Text("Normal")
               }
           }
        case .vibrant:
           Text("Full color")
        }
    }
}

まとめ

待望の空間Widgetに、たくさんのアプリが対応してくれるのが楽しみですね!

Related Entries
Latest Entries