在前面的文章中《iOS创建App小组件(Widget)》,讲到如何创建小组件以及展示了创建第一个小组件的过程。
本文则以上一篇的知识为基础,进一步扩展为设置多个App小组件,提供不同尺寸的视图配置。
在 WidgetKit 中,默认情况下,一个小组件可能会展示为多个不同的大小(如 .systemSmall, .systemMedium, .systemLarge),这些大小由系统自动决定,取决于屏幕空间和布局需求。

要使每个小组件在不同的大小下有不同的行为,需要明确指定每个小组件的大小配置。
1、小组件配置:如果没有明确指定小组件的大小,系统可能会自动选择可用的多个大小。
2、预览配置:如果使用了 #Preview 进行预览,它可能会显示多个尺寸的小组件,而不仅仅是期望的一个固定大小。
设置多个小组件
如果希望为不同的尺寸提供不同的视图配置,可以使用 WidgetConfiguration 来区分不同的小组件尺寸。需要使用 Widget 的 body 中的 WidgetConfiguration 来为每种尺寸提供具体的视图和配置。
1、使用 .systemSmall, .systemMedium, .systemLarge 来指定不同的视图:
可以根据尺寸大小设置不同的视图。可以在 Widget 的配置中使用不同的视图来针对不同的尺寸做调整。
struct BankletWidget: Widget {
let kind: String = "BankletWidget"
var body: some WidgetConfiguration {
AppIntentConfiguration(kind: kind, intent: ConfigurationAppIntent.self, provider: Provider()) { entry in
BankletWidgetEntryView(entry: entry)
.containerBackground(for: .widget) {
Image("WidgetBackground")
}
}
.supportedFamilies([.systemSmall]) // 支持小尺寸
}
}

如果要显示多个不同尺寸的视图,可以创建多个Widget文件:
// 小组件 1:显示背景的 BankletWidgetBackground
struct BankletWidgetBackground: Widget {
let kind: String = "BankletWidgetBackground"
var body: some WidgetConfiguration {
// 定义一个简单的 widget 配置
StaticConfiguration(kind: kind, provider: Provider()) { entry in
BankletWidgetBackgroundView(entry: entry)
.containerBackground(for: .widget) {
Image("WidgetBackground")
.resizable()
.scaledToFill() // 确保背景填充整个 widget
.clipped()
}
}
.supportedFamilies([.systemSmall]) // 支持小尺寸
}
}
// 小组件 2:显示内容的 BankletWidgetEntry
struct BankletWidgetEntry: Widget {
let kind: String = "BankletWidgetEntry"
var body: some WidgetConfiguration {
// 定义另一个 widget 配置
StaticConfiguration(kind: kind, provider: Provider()) { entry in
BankletWidgetEntryView(entry: entry)
.containerBackground(for: .widget) {
Image("WidgetBackground")
}
}
.supportedFamilies([.systemSmall]) // 支持小尺寸
}
}
在BankletWidgetBundle文件中,显示这两个Widget结构:
import WidgetKit
import SwiftUI
@main
struct BankletWidgetBundle: WidgetBundle {
var body: some Widget {
BankletWidget()
BankletWidgetBackground()
}
}
最后,在真机上可以查看到对应的小组件。

需要注意的是,创建Widget时,每个小组件的kind唯一并且正确配置,如果多个小组件使用相同的kind,可能导致多个小组件的内容为同一个。
2、在 #Preview 中设置特定尺寸:
可以通过 timeline 配置来为每个尺寸单独设置预览。可以为不同的小组件指定不同的尺寸,以便预览时查看不同尺寸的效果。
#Preview(as: .systemSmall) {
BankletWidget()
} timeline: {
SimpleEntry(date: .now, configuration: ConfigurationAppIntent())
}
#Preview(as: .systemMedium) {
BankletWidget()
} timeline: {
SimpleEntry(date: .now, configuration: .smiley)
SimpleEntry(date: .now, configuration: .starEyes)
}

相关文章
iOS创建App小组件(Widget):https://fangjunyu.com/2025/02/15/ios%E5%88%9B%E5%BB%BAapp%E5%B0%8F%E7%BB%84%E4%BB%B6%EF%BC%88widget%EF%BC%89