在前面的文章中《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
 
				    

 
    