简介
Widgets显示相关的、可浏览的内容,允许用户快速访问您的应用程序以获取更多详细信息。
- Widget使用SwiftUI视图显示其内容
- 一个App 可以提供多种样式的 Widget
- 可以添加同一Widget 的多个副本 ,可以根据其独特的需求和布局定制每个 Widget
- Widget 支持大中小3种尺寸(systemLarge、systemMedium、systemSmall),你可以根据实际情况选择适合自己的尺寸(WidgetFamily控制)
添加Widget到工程
- 打开你的 Xcode 工程, 并且选择 File > New > Target.
- 在 Application Extension group 中选择 Widget Extension
- 输入 Widget 的名字
- 如果 Widget 提供了用户可配置的属性,请选中“ Include Configuration Intent ”复选框。
- 点击完成
详细配置信息

@main
struct IMYWidgetDemoTest: Widget {
private let kind: String = "IMYWidgetDemoTest"
public var body: some WidgetConfiguration {
IntentConfiguration(kind: kind, intent: ConfigurationIntent.self, provider: Provider(), placeholder: PlaceholderView()) {
entry in IMYWidgetDemoTestEntryView(entry: entry)
}
.configurationDisplayName("My Widget")
.description("This is an example widget.")
.supportedFamilies([.systemSmall, .systemMedium, .systemLarge])
}
}
- Kind:标识 Widget 的字符串。这是您选择的标识符,并且应描述 Widget 所代表的内容。
- Custom Intent:定义用户可配置属性。
- Provider:符合 TimelineProvider 的对象,该对象生成一个时间线,告诉 WidgetKit 何时渲染。时间线包含自定义的 TimelineEntry 类型。TimelineEntry 标识您希望 WidgetKit 更新 Widget 内容的日期,包括 Widget 视图需要渲染自定义类型的属性。
- Placeholder View:WidgetKit 使用一个 SwiftUI 视图来首次渲染。占位符是 Widget 的通用表示形式,没有特定的配置或数据。
- Content Closure:包含 SwiftUI 视图的关闭。 WidgetKit 调用此方法来渲染 Widget 内容,并从 provider 传递 TimelineEntry 参数。
TimelineProvider
struct Provider: IntentTimelineProvider {
//提供预览快照
public func snapshot(for configuration: ConfigurationIntent, with context: Context, completion: @escaping (SimpleEntry) -> ()) {
let entry = SimpleEntry(date: Date(), configuration: configuration)
completion(entry)
}
//刷新数据和控制下一步刷新时间
public func timeline(for configuration: ConfigurationIntent, with context: Context, completion: @escaping (Timeline<Entry>) -> ()) {
var entries: [SimpleEntry] = []
// Generate a timeline consisting of five entries an hour apart, starting from the current date.
let currentDate = Date()
for hourOffset in 0 ..< 5 {
let entryDate = Calendar.current.date(byAdding: .hour, value: hourOffset, to: currentDate)!
let entry = SimpleEntry(date: entryDate, configuration: configuration)
entries.append(entry)
}
let timeline = Timeline(entries: entries, policy: .atEnd)
completion(timeline)
}
}
刷新策略(policy):
- .atEnd:默认使用该策略,在时间轴中的条目指定的最后日期之后请求新的时间轴
- .never:永不更新,可以使用WidgetCenter函数reloadTimelines(ofKind :)来进行更新
- .after: 指定多久之后更新
Custom Intent
当我们在Intent的Parameters中添加content,在小组件上是可以看到,我们可以通过更改这个值并让它展示
struct IMYWidgetDemoTestEntryView : View {
var entry: Provider.Entry
var body: some View {
Text(entry.configuration.content ?? "Placeholder");
}
}
多个 WIDGETS
@main
struct Widgets: WidgetBundle {
@WidgetBundleBuilder
var body: some Widget {
IMYWidgetDemoTest()
IMYWidgetDemoTest1()
}
}
参考链接