Today Widget 是一个 iOS 扩展,它直接在通知中心或“今天”屏幕上显示交互式信息。用户可以看到最新数据——天气、汇率、日历——而无需打开主应用程序。根据 Apple WWDC (2025) 的数据,在 iOS 17 引入交互式小组件后,WidgetKit 的使用量增长了 40%。Today Widget 解决了快速获取信息的问题:看一眼屏幕——用户无需在应用程序中导航即可获得所需数据。
要点
Today Widget(也称为通知中心小组件)—— 是一个 iOS 界面元素,无需启动应用程序即可显示其中的压缩信息。用户在锁定屏幕或主屏幕上向左滑动即可看到小组件。小组件可以显示动态数据——汇率、最新新闻、任务状态、设备状况。
从历史上看,Today Widget 出现在 iOS 8 中,作为通知中心的扩展,通过 Notification Center 框架实现。随着 iOS 14 的推出,Apple 引入了 WidgetKit——一个完全重新设计的架构,允许将小组件直接放置在桌面上。现代意义上的 Today Widget 是放置在“今天”部分(第一个屏幕左侧的小组件部分)的 WidgetKit 小组件。
主要目标是减少获取信息的时间。用户无需打开应用程序、导航菜单和等待加载,而是立即看到所需数据。根据 Apple(2024)的数据,带有小组件的应用程序的用户互动率 高出 27%。其他场景:快速操作(标记任务为已完成)、监控(脉搏、活动)和状态(电池充电、通知)。
Today Widget 开发人员有两种方法:现代的 WidgetKit(iOS 14+)和旧版扩展 NCWidgetProviding(iOS 8–13)。选择取决于最低支持的 iOS 版本。WidgetKit 推荐用于新项目,NCWidgetProviding 用于支持旧设备。
| 特性 | WidgetKit | NCWidgetProviding |
|---|---|---|
| 最低 iOS | iOS 14 | iOS 8 |
| 位置 | 桌面 + “今天” | 仅“今天” |
| 尺寸 | Small, Medium, Large | 固定一种 |
| 交互性 | iOS 17+ 按钮和开关 | 仅打开应用程序 |
| 更新 | Timeline Provider | widgetPerformUpdate |
| 语言 | SwiftUI | UIKit |
如果您的应用程序支持 iOS 14 及以上版本——请使用 WidgetKit。它提供丰富的功能:多种尺寸、通过 intent 进行配置、iOS 17 的重新设计和深层链接。SwiftUI 声明式编程使小组件代码紧凑且可读。Timeline Provider 自动管理更新计划,同时考虑能耗。
仅当需要支持 iOS 9–13 时。NCWidgetProviding 实现更简单——它是一个带有协议的普通 UIViewController。但它很有限:单一尺寸、仅 UIKit、没有配置。Apple 建议即使对于旧项目也使用 availability check 迁移到 WidgetKit:iOS 14+ 使用 WidgetKit,NCWidgetProviding 作为后备。
在现代 iOS 中,根据功能用途区分了三种类型的小组件。每种类型解决自己的任务,需要对数据和界面的设计采取不同的方法。分类有助于为您的应用程序选择正确的架构。
显示静态或定期更新的信息:天气、日期、汇率、服务器状态。数据通过 Timeline Provider 按计划更新。用户不与小组件交互——只阅读。信息类小组件实现最简单,不需要处理触摸事件,在后台无需额外权限即可运行。
从 iOS 17 开始,WidgetKit 支持小组件中的按钮、开关和滑块。用户无需打开应用程序即可执行操作——标记任务、暂停音乐、打开灯光。Interactive Widgets 使用 App Intents 将操作传递到主应用程序。限制:仅在桌面上,在 iOS 18 之前不在“今天”部分中。
用户通过系统界面自定义显示的数据——选择城市查看天气、账户查看财务、类别查看新闻。通过 Intents Extension 和 WidgetBundle 中的配置实现。可配置小组件提高了每个用户的个性化和信息的相关性。
让我们看看使用 WidgetKit 在 SwiftUI 中创建 Today Widget 的过程。该小组件将显示当前汇率并自动更新。WidgetKit 需要三个组件:小组件结构、带配置的 Provider 和用于显示的 View。
import WidgetKit
import SwiftUI
@main
struct CurrencyWidget: Widget {
let kind: String = "CurrencyWidget"
var body: some WidgetConfiguration {
StaticConfiguration(kind: kind, provider: Provider()) { entry in
CurrencyWidgetEntryView(entry: entry)
}
.configurationDisplayName("Currency Rate")
.description("Current USD/RUB exchange rate")
.supportedFamilies([.systemSmall, .systemMedium])
}
}
Provider 负责准备要显示的数据。getTimeline 方法创建更新计划:下一次更新在 15 分钟后。TimelineProvider 确保小组件在不持续轮询服务器的情况下显示最新数据。
struct Provider: TimelineProvider {
func getSnapshot(in context: Context,
completion: @escaping (CurrencyEntry) -> Void) {
let entry = CurrencyEntry(date: Date(), rate: 92.5)
completion(entry)
}
func getTimeline(in context: Context,
completion: @escaping (Timeline<CurrencyEntry>) -> Void) {
let rate = CurrencyService().fetchRate()
let entry = CurrencyEntry(date: Date(), rate: rate)
let nextUpdate = Calendar.current.date(
byAdding: .minute, value: 15, to: Date()
) ?? Date()
let timeline = Timeline(entries: [entry], policy: .after(nextUpdate))
completion(timeline)
}
}
Timeline Provider 是 WidgetKit 管理 Today Widget 数据的核心机制。WidgetKit 不使用定时器定期更新(如旧的 NCWidgetProviding),而是使用 timeline 概念——带有时间戳的记录序列。系统显示当前记录直到其过期,然后切换到下一个或请求新的记录。
Timeline 支持三种策略:.after(date) — 在指定日期进行下一次更新;.never — 小组件在显式调用 WidgetCenter.reloadAllTimelines 之前不更新;.atEnd — 在显示最后一条记录后更新。对于显示汇率的 Today Widget,.after 策略间隔 15–30 分钟是最优的。能效是 WidgetKit 的关键优势:系统将所有小组件的更新分组到一个窗口中。
如果数据在 timeline 过期前发生了变化(例如用户在应用程序中更新了汇率),请调用 WidgetCenter.shared.reloadTimelines(ofKind: "CurrencyWidget")。这将从 Provider 请求新的 timeline 并更新显示。WidgetCenter 还允许通过一个命令重新加载应用程序的所有小组件——在数据同步后很方便。
Apple 对 Today Widget 的设计提出了严格要求:内容必须从远处可读,没有多余元素,层次结构清晰。违反 HIG(Human Interface Guidelines)建议是在 App Store 发布时被拒绝的原因。三个原则:glanceability、consistency 和 hierarchy。
用户在小组件上花费的时间不到一秒。不要添加超过 3–4 个数据元素。字体——标签至少 11pt,数值至少 17pt。关键数字使用粗体(Semibold)。避免滚动——Today Widget 不可滚动。
WidgetKit 支持三种尺寸:Small(170×170pt)、Medium(364×170pt)、Large(364×382pt)。对于“今天”部分中的 Today Widget,Medium 是最常见的选择。自适应设计通过 EnvironmentValues:根据尺寸改变信息密度。Small — 一个数字,Medium — 数字 + 图表,Large — 表格。
小组件必须在亮色和深色主题下正确显示,无需开发人员额外操作——WidgetKit 自动获取系统颜色。小组件的 Dynamic Type 有限:字体大小固定但必须可读。UIColor.label 和 UIColor.systemBackground — 两种主题下文本和背景的基本颜色。
常见问题
如今它们是同一个 WidgetKit 小组件。区别仅在于位置:在桌面上和在“今天”部分(第一个屏幕的左侧)。在 iOS 14 之前,Today Widget 是一个单独的 NCWidgetProviding 扩展,仅在通知中心中工作。现在它是一个统一的 WidgetKit。
WidgetKit 不使用定时器更新小组件。开发人员通过 Timeline Provider 设置计划:带有时间戳的记录。系统在考虑节能的情况下保证在指定时间更新——可能会延迟几分钟。最小间隔为 15 分钟,但 Apple 建议不超过每小时 1 次。
可以,从 iOS 17 开始,WidgetKit 通过 App Intents 支持按钮、开关和滑块。交互式元素在 iPhone 和 iPad 桌面上工作。在“今天”部分中的支持出现在 iOS 18。对于 iOS 16 及更早版本——仅点击小组件时打开应用程序。
没有限制。应用程序可以通过 WidgetBundle 注册任意数量的小组件——每个都有自己的类型、尺寸和配置。用户单独添加它们。建议不超过 3–5 个小组件,以免使用户选择过载。
WidgetKit 在 iOS Simulator 中完全支持。在 Xcode 中运行 WidgetKit target 方案——小组件将出现在模拟器桌面上。要检查 Timeline Provider,请使用 WidgetKit Debug Profile:Xcode → Product → Profile → WidgetKit Debug。在实际设备上验证真实行为。
总结
我们将开发一款交钥匙移动应用程序
IT Sectr自2017年以来为初创企业和企业打造iOS和Android应用程序。我们将为您提供咨询并提出最佳解决方案。