業務で自分がウィジェット対応した際に必要だった知見が何個かあったのでまとめておく
これからウィジェット対応する人の手助けになれば
サイズ指定
struct SampleWidget: Widget {
var body: some WidgetConfiguration {
StaticConfiguration(kind: "sample", provider: SampleWidget.Provider()) { entry in
SampleWidgetEntryView(entry: entry)
}
.supportedFamilies([.systemSmall, .systemMedium])
.configurationDisplayName("displayName")
.description("description")
}
}
WidgetBundleで複数ウィジェット
WidgetBundleで複数パターンのウィジェットを設定可能
@main
アノテーションを忘れずに
@main
struct Widgets: WidgetBundle {
var body: some Widget {
Widget1()
Widget2()
Widget3()
}
}
Imageの角丸
ウィジェット自体が角丸なので、画像も角丸にするのが定石だと思うので
clipshape
とRoundedRectangle
で可能
iOS14から登場した.clipShape(ContainerRelativeShape())
でOSが自動で角丸描画してくれるが、近接する要素によって思い通りの角丸にならないケースがあるので注意
struct ImageView: View {
let image: UIImage
var body: some View {
Image(uiImage: image)
.resizable()
.scaledToFit()
.clipShape(RoundedRectangle(cornerRadius: 8))
}
}
プレビュー
ライトモード、ダークモード、プレースホルダー、サイズ違いを一気に確認したいと思うので
ウィジェットサイズ
previewContext
.previewContext(WidgetPreviewContext(family: .systemMedium))
で指定
ライトモード、ダークモード
colorScheme
.environment(\.colorScheme, .light)
で指定
プレースホルダ
.redacted(reason: .placeholder)
で指定
struct SampleWidget_Previews: PreviewProvider {
static var previews: some View {
/// ライトモード
SampleEntryView(entry: .init(date: Date())
.previewContext(WidgetPreviewContext(family: .systemMedium))
.environment(\.colorScheme, .light)
/// ダークモード
SampleEntryView(entry: .init(date: Date())
.previewContext(WidgetPreviewContext(family: .systemMedium))
.environment(\.colorScheme, .dark)
/// プレースホルダー表示
SampleEntryView(entry: .init(date: Date())
.previewContext(WidgetPreviewContext(family: .systemMedium))
.redacted(reason: .placeholder)
}
}
SpacerのminLength
12ProMaxから初代SEまでのレイアウトに対応しなくていけなく、Spacer(minLength: length)
を結構使った
指定した座標分最低限スペースを取り、描画領域に余裕があれば自動で広がってくれるのでとても便利!