2020年06月22日的WWDC上iOS14的新特性-小部件正式在iOS上线,同时WidgetKit也正式面向广大开发者使用。git
也正是由于对Android的小部件有所了解,故想尝试下iOS的小部件的开发,而且发现当前并无相关的文章,故记录下我学习WigetKit的经历,如下均为本身学习路上的经历,可能会有些问题,还望大佬指正。github
同时已把学习路上写的代码开源 - iWiget,看完这篇文章认为有用就点个Star呗!api
项目地址: github.com/Littleor/iW…xcode
开发Widget须要使用到Xcode12,目前依旧是beta版本,须要在官网使用开发者帐号下载。bash
开发者帐号的注册是免费的,使用AppleId注册后直接下载使用便可。app
具体步骤网上有不少,这里再也不赘述。 ide
欲使用WidgetKit必先建立一个iOS的项目,按常规操做来便可。函数
点击Create a new Xcode Project来建立新项目 布局
选择iOS->App再点击Next 学习
Name随便填,Organization Identifier填写翻转域名便可。
建立完成就出现默认的Hello World!啦
首先点击左上角的File->New->Target添加Target
Provider实现了IntentTimelineProvider,主要用于提供数据和控制数据的刷新,其中有两个关键函数:public func snapshot(for configuration: ConfigurationIntent, with context: Context, completion: @escaping (SimpleEntry) -> ())
和 public func timeline(for configuration: ConfigurationIntent, with context: Context, completion: @escaping (Timeline<Entry>) -> ())
,其中snapshot会在Widget被添加的时候执行,timeline经过Timeline(entries: entries, policy: .atEnd)
刷新数据和控制下一步刷新时间.
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)
}
}
复制代码
这里只写如何使用,具体内容下一篇细述。
SimpleEntry实现了TimelineEntry,主要用于保存Widget的数据。
struct SimpleEntry: TimelineEntry {
public let date: Date
public let configuration: ConfigurationIntent
}
复制代码
PlaceholderView用于显示默认Widget,当Widget还没获取到数据的时候会默认显示这里的布局。
struct PlaceholderView : View {
var body: some View {
Text("Placeholder View")
}
}
复制代码
WidgetDemoEntryView是Widget的布局部分,是Widget的View的部分。
struct WidgetDemoEntryView : View {
var entry: Provider.Entry
var body: some View {
Text(entry.date, style: .time)
}
}
复制代码
这里能够说是Widget的入口了罢,这里定义了Widget的Kind
、Provider
、View
等。
@main
struct WidgetDemo: Widget {
private let kind: String = "WidgetDemo"
public var body: some WidgetConfiguration {
IntentConfiguration(kind: kind, intent: ConfigurationIntent.self, provider: Provider(), placeholder: PlaceholderView()) { entry in
WidgetDemoEntryView(entry: entry)
}
.configurationDisplayName("My Widget")
.description("This is an example widget.")
}
}
复制代码
iOS建立多个小部件不能像Android同样直接创建多个Widget的配置文件,不然会报错,而是能够直接修改当前Widget的入口文件便可,Apple提供了相关API:
@main
struct Widgets: WidgetBundle {
@WidgetBundleBuilder
var body: some Widget {
Widget1()
Widget2()
Widget3()
}
}
复制代码
改变@main为WidgetBundle,再建立多个Widget的struct便可.
在这几天对WidgetKit的学习后,从开发者的角度来讲,iOS的Widget开发实在让人温馨,而没有Android Widget开发的那种凌乱感(也多是我太菜了才感受凌乱...)
整体对iOS的Widget仍是很满意的,不管是开发体验仍是用户体验(除了iOS14 Public Beta在点击配置小部件的时候会卡一下)。
后续还会慢慢完善WidgetKit开发的文章,同时iWiget也会不断完善,这篇文章对你有用就点个Star吧!
项目地址: github.com/Littleor/iW…