IOS小组件(2):小组件框架解析
引言
看了小组件的概述,你肯定想马上搞一个小组件出来试试,实践中学习效果更佳
本文大纲
- 创建小组件
- 认识小组件框架各个组成部分
创建小组件
- 第一步:先创建好一个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开发入门等