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…