Swift Academy · 课时

构建 WidgetKit Widget

使用时间线创建主屏幕 Widget。

第 1 / 4 课13 个步骤

构建 WidgetKit Widget 是 CoddyKit 上的免费 Swift Academy 课时。 这是第 1 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Swift Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Swift Academy 课程共包含 4 节课。

什么是小组件

小组件是一种小型、便于一瞥查看的视图,位于主屏幕、锁定屏幕或 StandBy 中。它不是迷你应用——不能滚动,也不能运行任意代码。它会显示一份数据快照,由系统按照您通过 WidgetKit 提供的计划进行刷新。

import WidgetKit
import SwiftUI
// A widget = configuration + timeline of entries
// + a SwiftUI view that renders one entry

小组件扩展目标

小组件包含在独立的小组件扩展目标中,而不是主应用中。它拥有自己的程序包,并在独立的进程中运行。您可以通过 Xcode 的小组件扩展模板添加它,该模板会自动搭建配置和提供程序。

import WidgetKit
// File > New > Target > Widget Extension
// The extension declares one or more widgets
// in a WidgetBundle if you have several.

小组件类型

小组件遵循 Widget 协议,并公开一个返回配置的 body。该配置将类型标识符、时间线 提供程序以及用于渲染每个 entry 的视图关联起来。

import WidgetKit
import SwiftUI
struct WeatherWidget: Widget {
    var body: some WidgetConfiguration {
        StaticConfiguration(
            kind: "WeatherWidget",
            provider: WeatherProvider()) { entry in
            WeatherView(entry: entry)
        }
        .configurationDisplayName("Weather")
        .description("Shows the current forecast.")
    }
}

静态配置与 AppIntent 配置

StaticConfiguration适用于没有用户选项的小组件。AppIntentConfiguration允许用户通过应用意图自定义小组件(选择城市或账户)。固定内容应选择静态配置,可配置的小组件应选择基于意图的配置。

import WidgetKit
// StaticConfiguration     -> no user choices
// AppIntentConfiguration  -> user-editable parameters
let kinds = "static vs configurable"
_ = kinds

时间线条目

小组件可以显示的每个时间 point 都是一个 TimelineEntry——一个包含 date以及视图所需其他数据的结构体。提供程序会提供一系列这样的 entries。

import WidgetKit
struct WeatherEntry: TimelineEntry {
    let date: Date
    let temperature: Int
    let condition: String
}

小组件视图

视图使用普通的 SwiftUI,但受到一定限制:不能滚动,交互功能有限,而且必须在几种固定尺寸下都呈现良好效果。读取 entry,并布局一份简洁、便于一瞥查看的摘要。

import SwiftUI
import WidgetKit
struct WeatherView: View {
    let entry: WeatherEntry
    var body: some View {
        VStack {
            Text(entry.condition)
            Text("\(entry.temperature) degrees")
                .font(.title)
        }
    }
}

支持的尺寸类别

使用 supportedFamilies声明支持的尺寸:.systemSmall、.systemMedium、.systemLarge、锁定屏幕上的 .accessoryRectangular/.accessoryCircular 等。使用小组件 family 环境,针对每个 family 调整布局。

import WidgetKit
import SwiftUI
// .configurationDisplayName(...)
// .supportedFamilies([.systemSmall, .systemMedium,
//                     .accessoryRectangular])
let families = "declare supported sizes"
_ = families

适配不同尺寸类别

在视图中读取 @Environment(\.widgetFamily),即可根据不同情况切换布局——例如紧凑的小型小组件与内容更丰富的中型小组件——而无需编写多个独立的小组件。

import SwiftUI
import WidgetKit
struct AdaptiveView: View {
    @Environment(\.widgetFamily) var family
    let entry: WeatherEntry
    var body: some View {
        if family == .systemSmall {
            Text("\(entry.temperature)")
        } else {
            Text("\(entry.condition) \(entry.temperature)")
        }
    }
}

容器背景

现代小组件必须使用 containerBackground(for: .widget)声明背景,以便系统在 StandBy 和锁定屏幕等不同场景中正确渲染。缺少此声明时,小组件可能会被拒绝,或者显示效果不正确。

import SwiftUI
import WidgetKit
struct Bg: View {
    var body: some View {
        Text("Hi")
            .containerBackground(for: .widget) {
                Color.blue
            }
    }
}

与应用共享数据

小组件进程是独立的,因此无法读取应用的内存状态。请通过应用组共享数据——这是两个目标都能访问的共享容器——通常使用共享的 UserDefaults套件或应用组容器中的文件。

import Foundation
let shared = UserDefaults(
    suiteName: "group.com.example.app")
// App writes; widget reads the same suite.
_ = shared

重新加载小组件

当应用数据发生变化时,请调用 WidgetCenter.shared.reloadTimelines(ofKind:)(或 reloadAllTimelines())通知 WidgetKit 刷新。这会促使系统向您的提供程序请求新的时间线。

import WidgetKit
func refreshWidget() {
    WidgetCenter.shared.reloadTimelines(
        ofKind: "WeatherWidget")
}

快速检查

回想一下小组件如何与其宿主应用共享数据。

回顾

您构建了一个 WidgetKit 小组件:

  • 小组件位于独立扩展中,遵循 Widget协议,并返回一个 WidgetConfiguration。
  • 使用 StaticConfiguration或 AppIntentConfiguration、一个 TimelineEntry以及受限的 SwiftUI 视图。
  • 声明 supportedFamilies,通过 widgetFamily进行适配,并添加 containerBackground。
  • 通过应用组共享数据,并使用 WidgetCenter.reloadTimelines刷新。
免费开始

用 AI 导师学习 Swift — 免费

在浏览器中编写并运行真实代码,获得全天候 AI 导师的即时帮助,并在网页或应用中继续学习。

课程
122
课程
409

常见问题解答

「构建 WidgetKit Widget」课时是免费的吗?

是的 — 「构建 WidgetKit Widget」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Swift Academy 课程的其余内容,请升级到 CoddyKit PRO。 Swift Academy 课程共包含 4 节课。

「构建 WidgetKit Widget」这节课中我会学到什么?

使用时间线创建主屏幕 Widget。 你通过在浏览器中直接运行的动手代码来练习 Swift Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 Swift Academy 需要有经验吗?

无需任何先前经验。CoddyKit 上的 Swift Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 1 节课,共 4 节。

「构建 WidgetKit Widget」课时需要多长时间?

大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。

我能在这节 Swift Academy 课中编写并运行代码吗?

能。每节 Swift Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。

此课程中的所有课时

  1. 构建 WidgetKit Widget
  2. 时间线提供程序与快照
  3. 应用扩展概览
  4. 应用意图与快捷指令
← 返回 Swift Academy