1. SwiftUI_Widget 小组件使用
1.1. 为项目添加Widget
Project -> Targets -> + -> 选择WidgetExtension
运行项目长按屏幕,点击左上角的➕来选择对应项目的小组件;
在XXXWidget.swift文件中
1.2. TimelineProvider 时间线提供者
建议WidgetKit何时更新窗口小部件显示的类型。
在不同的时间,WidgetKit向提供者请求_timeline_。 时间线是符合<doc:TimelineEntry>的对象数组。 每个时间轴条目都有一个日期,您可以指定其他属性来显示小部件。
1.3. IntentTimelineProvider 意图时间线提供者
建议WidgetKit何时更新用户可配置的窗口小部件显示的类型。
Intent时间轴提供程序执行与相同的功能,但是它还将用户配置的详细信息合并到时间轴条目中。
struct Provider: IntentTimelineProvider {
// 设置占位渲染的数据
func placeholder(in context: Context) -> SimpleEntry {
SimpleEntry(date: Date(), configuration: ConfigurationIntent(), myCount: "-")
}
// 在添加小组件时,预览需要的数据(预览渲染)
func getSnapshot(for configuration: ConfigurationIntent, in context: Context, completion: @escaping (SimpleEntry) -> ()) {
let entry = SimpleEntry(date: Date(), configuration: configuration, myCount: "-")
completion(entry)
}
// 小组件在屏幕上渲染时调用,用来设置TimeLine和数据 (TimeLine相当于小组件的引擎)
// 在编辑配置小组件时会重新调用
func getTimeline(for configuration: ConfigurationIntent, in 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, myCount: "--")
entries.append(entry)
}
let timeline = Timeline(entries: entries, policy: .atEnd)
completion(timeline)
}
}
1.4. TimelineEntry 时间线条目项
一种类型,指定显示小部件的日期,并可选地指示小部件内容的当前相关性。
//
struct SimpleEntry: TimelineEntry {
//WidgetKit呈现小部件的日期。
let date: Date
// 配置意图信息
let configuration: ConfigurationIntent
// 自定义数据
let myCount: String
//小部件的内容与用户的相关性。
var relevance: TimelineEntryRelevance? { get }
}
// 小组件显示主体
struct MyWidgetEntryView : View {
var entry: Provider.Entry
var body: some View {
Text("Hello, Widget")
}
}
1.5. TimelineEntryRelevance 时间线输入相关性
用于描述时间线条目与当前和过去时间线中的其他条目相比的相对重要性。
当用户将小部件放入堆栈中时,WidgetKit使用时间线提供者生成的条目的TimelineEntry / relevance-2oovl属性来确定它们与用户的相关性。 对于提供商创建的每个时间线条目,您可以分配相关性,其中包含TimelineEntryRelevance / score和TimelineEntryRelevance / duration。 分数是您选择的一个值,该值指示窗口小部件相对于提供商创建的时间轴上的条目的相关性。 当条目的日期到达时,并且在您指定的持续时间内,WidgetKit可能会将您的窗口小部件旋转到堆栈的顶部,从而使其可见。
例如,考虑显示股票市场信息的小部件。 在开放市场时段,该小部件比关闭市场时更相关。 此外,用户关注列表中的股票比不在关注列表中的股票更相关。 结果,市场时段的条目得分更高,而显示关注列表股票的条目得分甚至更高。
一个不同的示例可能是显示游戏角色健康状况的小部件。 在健康水平恢复期间,它可能比达到100%时更重要。 相反,您可能会决定角色的小部件的相关性降低,直到其健康级别达到100%。 只有您才能确定小部件的内容与用户的相关程度。
当您可以确定时间轴条目的相对重要性时,请在您创建的条目上设置relevance
属性。 WidgetKit在您指定的持续时间内在多个时间轴上维护相关性信息。 在生成具有正分数的相关性的时间线条目后,如果您创建后续时间线并希望保持原始的相关性,则将“ relevance”属性设置为“ nil”。 要删除先前的相关性,或指定WidgetKit不考虑将窗口小部件旋转到堆栈顶部,请将“相关性”属性的得分设置为零(0)
为了确定单个条目的分数,最好从绝对无关性到最相关性来确定绝对比例。 比例尺的范围完全由您决定,可以是1到100、50到5000或其他对您有意义的正数范围。 WidgetKit计算条目之间得分的相对差异,因此绝对值无关紧要。
由于WidgetKit会在时间轴上维护关联性信息,因此您应该对所有时间轴使用一致的比例。 为简单起见,您可以使用具有特定值的枚举,以实现“低”,“中”和“高”相关性。 另外,如果您的分数计算具有连续变化,则可以在标尺中使用浮点精度,并且最小值和最大值保持一致。
零(0)或更低的分数表示微件无关,并且WidgetKit不会考虑将其旋转到堆栈的顶部。
当小部件位于堆栈中,并且用户为堆栈启用了智能旋转时,WidgetKit通常会限制其考虑将小部件旋转到堆栈顶部的次数。 要在开发过程中绕过此限制,请在“设置”>“开发人员”中启用“ WidgetKit开发人员模式”开关。
小组件入口
@main
struct MyWidget: Widget {
let kind: String = "MyWidget"
var body: some WidgetConfiguration {
// 描述使用自定义意图定义提供用户可配置选项的小部件的内容。
IntentConfiguration(kind: kind, intent: ConfigurationIntent.self, provider: Provider()) { entry in
MyWidgetEntryView(entry: entry)
}
//在用户添加或编辑其小部件时显示详细信息。
.configurationDisplayName("My Widget")
.description("This is an example widget.")
.supportedFamilies([.systemMedium,.systemLarge])
}
}
-
kind: 每个小部件都有一个唯一的
kind
,即您选择的字符串。 在使用WidgetCenter重新加载其时间线时,可以使用此字符串来标识您的窗口小部件。 -
Intent: 是一个自定义的SiriKit Intent定义,其中包含用户可编辑的参数。
-
provider: 时间线提供者是一个确定刷新小部件的时间线的对象。 提供将来更新小部件的日期可以使系统优化刷新过程。
-
内容闭合包含WidgetKit呈现小部件所需的SwiftUI视图。 当WidgetKit调用内容闭包时,它将传递由小部件提供程序的 WidgetKit/IntentTimelineProvider/getSnapshot 或 WidgetKit/IntentTimelineProvider/getTimeline 创建的时间线条目方法。
持续更新中。。。