引言
看了小組件的概述,你肯定想馬上搞一個小組件出來試試,實踐中學習效果更佳
本文大綱
- 創建小組件
- 認識小組件框架各個組成部分
創建小組件
- 第一步:先創建好一個App,步驟省略
- 第二步:在App中創建小組件
1. 在Xcode中打開您的應用程序項目,然后選擇 File > New > Target。
2. 從“Application Extension”組中,選擇“Widget Extension”,然后單擊“Next”。
3. 輸入小組件的名稱。
4. 如果需要給小組件提供用戶可配置的屬性,請選中“Include Configuration Intent”復選框。
5. 單擊 Finish。
認識小組件框架各個組成部分
如果沒有勾選“Include Configuration Intent”,默認生成如下代碼,這里新建的時候小組件的名字是 “Widget1”
//
// Widget1.swift
// Widget1
//
import WidgetKit
import SwiftUI
// 時間線刷新策略控制
struct Provider: TimelineProvider {
// 窗口首次展示的時候,先展示占數據
func placeholder(in context: Context) -> SimpleEntry {
SimpleEntry(date: Date())
}
// 添加組件時的預覽數據
func getSnapshot(in context: Context, completion: @escaping (SimpleEntry) -> ()) {
let entry = SimpleEntry(date: Date())
completion(entry)
}
// 時間線刷新策略控制邏輯
func getTimeline(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)
entries.append(entry)
}
let timeline = Timeline(entries: entries, policy: .atEnd)
completion(timeline)
}
}
struct SimpleEntry: TimelineEntry {
// 默認帶了一個日期參數
let date: Date
}
struct Widget1EntryView : View {
// 組件數據
var entry: Provider.Entry
// 這個 body 中就是自己需要實現的組件布局
var body: some View {
Text(entry.date, style: .time)
}
}
// 小組件入口
@main
struct Widget1: Widget {
// 小組件的唯一ID
let kind: String = "Widget1"
var body: some WidgetConfiguration {
// 創建時不勾選 “Include Configuration Intent”,這里使用 StaticConfiguration
StaticConfiguration(kind: kind, provider: Provider()) { entry in
Widget1EntryView(entry: entry) // 小組件UI
}
.supportedFamilies([.systemSmall, .systemLarge]) // 配置該組件支持的尺寸,如果不配置,默認是大中小都支持
.configurationDisplayName("組件標題") // 在添加組件預覽界面顯示
.description("組件描述") // 在添加組件預覽界面顯示
}
}
// 調試預覽
struct Widget1_Previews: PreviewProvider {
static var previews: some View {
Widget1EntryView(entry: SimpleEntry(date: Date()))
.previewContext(WidgetPreviewContext(family: .systemSmall))
}
}
運行上面的代碼,在桌面添加一個小組件,效果如下(對着圖再看上面的代碼注釋就能一一對應上)
小組件核心代碼
// 小組件入口
@main
struct Widget1: Widget {
// 小組件的唯一ID
let kind: String = "Widget1"
var body: some WidgetConfiguration {
// 創建時不勾選 “Include Configuration Intent”,這里使用 StaticConfiguration
StaticConfiguration(kind: kind, provider: Provider()) { entry in
Widget1EntryView(entry: entry) // 小組件UI
}
.supportedFamilies([.systemSmall, .systemLarge]) // 配置該組件支持的尺寸,如果不配置,默認是大中小都支持
.configurationDisplayName("組件標題") // 在添加組件預覽界面顯示
.description("組件描述") // 在添加組件預覽界面顯示
}
}
小組件核心代碼注解如下:
- kind是標識小組件的唯一ID
- body也是必須實現的,返回小組件的配置信息
- StaticConfiguration 標識小組件不支持動態修改配置(后面會詳細展開)
.supportedFamilies 設置小組件的尺寸類型,總共三種:.systemSmall, .systemMedium, .systemLarge
.configurationDisplayName("組件標題")
.description("組件描述") - Provider是給小組件提供刷新策略以及給小組件准備數據的核心
- Widget1EntryView(entry: entry),根據Provider提供的數據實體entry繪制小組件的UI
結語
默認新建一個小組件,開發工具已經默認生成了一份完整的小組件代碼。后續文章會詳細講解其中的各個細節點,比如:Provider的刷新機制,小組件的動態配置,SwiftUI開發入門等