SwiftUIでWidgetの背景の周囲の色が変わってしまう問題の解決方法
iOS17でウィジェットの背景が白(ダークモードでは黒)になってしまった場合の修正方法
はじめに
iOS14からウィジェット機能が追加され、OSアップデートごとにウィジェットのカスタマイズ性はどんどん拡張されていっています。
運用しているアプリでも採用しており、サイズごとに以下のとおりの表示になっています。
問題
iOS17のiPhoneにおいて、ホームに貼り付けていたウィジェットが以下のとおり、水色だった背景の周囲が白くなるようになってしまっていました。
iOS17.5に上げたタイミングで気づきましたが、Xcode15に上げてからアプリをアップデートしたことで、この問題が顕在化したので、どうやらXcode15でビルドした+iOS17系の条件でこの問題が発生したようです。
なお、画像では背景が白くなっていますが、ダークモードの場合は黒くなります。
この時点で、従来のコードでは指定できていない領域の背景に関わる仕様が変わったのではないかと推測できます。
ウィジェットを配置する際のプレビューも同様の問題が発生していました。
解決方法
問題解決の糸口は、ウィジェットプレビューを表示するウィンドウのエラーにありました。
containerBackgroundを使いましょうということです。
そこで以下のような独自クラスを作成して対応しました。
独自のWidgetについて書いているSwiftUIのファイルに、containerBackgroundを指定する以下のようなextensionを追記します。
extension View {
func widgetBackground(_ backgroundView: some View) -> some View {
if #available(iOSApplicationExtension 17.0, *) {
return containerBackground(for: .widget) {
backgroundView
}
} else {
return background(backgroundView)
}
}
}
そして、以下のとおり独自ウィジェットのメインのViewに、その拡張を使って色指定すれば解決しました。
struct xxWidgetEntryView : View {
var entry: Provider.Entry
@Environment(\.widgetFamily) var family
var body: some View {
ZStack(alignment: .topLeading, content: {
Color("AccentColor")
VStack(alignment: .leading, spacing: 6, content: {
...
}).padding(.all, 6)
})
.widgetBackground(Color("AccentColor")) //←ここを追加
}
}
ちなみにColor("AccentColor")が、従来の背景色の水色を指しています。
すると、先程エラーが出ていたプレビュー画面に、きちんとプレビューが表示され、背景も直っていることが確認できました。
参考
containerBackgroundをmodifierする必要があるということは、以下のWWDC2023のセッションでも説明されていたようです。