iOS 26 的小组件表面:一个 App Intent,多处呈现
多年来,小组件不过是一张快照。系统按时间线渲染您的视图,用户看一眼,任何点按都只会打开应用。这套模式已经成为过去。自 iOS 17 起,小组件就能承载按钮和开关,它们无需启动任何东西就能执行代码,而它们执行的正是一个 App Intent1。控制中心的控件如此,实时活动内部的按钮也是如此。一旦看清这一点,iOS 26 的小组件表面就不再像三个彼此独立的 API,而是合而为一:它们是系统渲染您 App Intents 的若干处场所,各自占据不同的展示空间,底层管线却完全相同。
这一重新定位正是本文的核心。把 App Intent 学透一次,您就点亮了主屏幕、锁屏、控制中心、操作按钮、灵动岛,乃至(还是同一个 intent)Siri 和 Apple Intelligence。若把它们当成三个互不相干的功能去写,您将付出四倍的工作量,换来更糟的结果。
摘要
- 交互式小组件(iOS 17+): 在小组件视图中放入
Button(intent:)或Toggle(isOn:intent:);系统会在您的小组件扩展中、脱离应用本体运行该 App Intent 的perform(),随后重新加载时间线1。 - 控制中心控件(iOS 18+): 由
ControlWidgetButton或ControlWidgetToggle构建的ControlWidget,背后由同一批 App Intents 支撑,可在控制中心、锁屏以及操作按钮上呈现2。 - 实时活动(ActivityKit):
ActivityAttributes加上ActivityConfiguration驱动锁屏和灵动岛;由服务器驱动的更新通过推送送达,而其中的按钮同样是 App Intents3。 - iOS 26 改的是渲染,而非模型: 小组件获得了 Liquid Glass 呈现方式和强调色渲染模式,但“App Intents 即表面”的架构自 iOS 18 以来并无变化4。
- 那条贯穿始终的事实是:小组件按钮、控件、Siri 短语、Apple Intelligence 操作,都可以是同一个 App Intent。能力只需设计一次。
交互式小组件:那个不打开应用的按钮
机制很小,值得精确陈述。您往小组件的视图里加一个 SwiftUI Button 或 Toggle,但传入的不是一个 action 闭包,而是一个 App Intent1:
struct WaterWidgetView: View {
let logged: Int
var body: some View {
VStack {
Text("\(logged) glasses")
Button(intent: LogWaterIntent()) {
Label("Add", systemImage: "plus")
}
}
}
}
用户点按时,系统会在您的小组件扩展内运行 LogWaterIntent.perform()。应用不会启动。该 intent 完成自己的工作(写入共享存储、更新计数),随后小组件时间线重新加载以展示结果。
Toggle 通过 SetValueIntent 以同样的方式工作,它会接收到用户刚刚设定的新开/关值:
struct ToggleReminderIntent: SetValueIntent {
static let title: LocalizedStringResource = "Toggle Reminder"
@Parameter(title: "Enabled")
var value: Bool
func perform() async throws -> some IntentResult {
ReminderStore.shared.enabled = value
return .result()
}
}
小组件绑定 Toggle(isOn: store.enabled, intent: ToggleReminderIntent()),系统将 value 设为新状态,运行 perform(),然后重新加载。和按钮的形态一致,只是多了一个参数1。
两条约束界定了您在这里能做什么,而它们都很容易被违反。其一,perform() 运行在受限的小组件扩展环境中,执行预算很紧;它适合做一次快速的状态变更,而非网络上传或繁重计算。其二,小组件反映状态,却不会播放任意 UI 动画。您改变数据,时间线随之重新渲染;您无法运行自定义过渡动画。把交互设计成“翻转一个值,展示这个新值”,它就能跑通。一旦想要更多,系统就会与您较劲。
控制中心控件:同一个 intent,换一个房间
iOS 18 把控制中心、锁屏和操作按钮向第三方控件开放,其 API 刻意与小组件保持平行2。一个控件就是一个 ControlWidget,其主体是一个接到 App Intent 上的 ControlWidgetButton 或 ControlWidgetToggle:
struct LogWaterControl: ControlWidget {
var body: some ControlWidgetConfiguration {
StaticControlConfiguration(kind: "com.example.logWater") {
ControlWidgetButton(action: LogWaterIntent()) {
Label("Log Water", systemImage: "drop.fill")
}
}
}
}
如果 LogWaterIntent 已经在驱动您的交互式小组件,那这个控件几乎是白送的:同一个 intent,换一层包装。这正是架构开始回报的时刻。控件并非该功能的第二套实现,而是为您已经写好的那一个功能提供的第二个挂载点。开关型控件用 SetValueIntent,与小组件开关的用法分毫不差,于是“静音”“开始会话”“切换深色模式”这类只构建一次的能力,无需新逻辑便会出现在控制中心、锁屏和操作按钮上2。
实时活动:会自我更新的表面
实时活动是第三处场所,也是活动部件最多的一处。ActivityAttributes 类型定义静态与动态内容,ActivityConfiguration 渲染锁屏呈现和灵动岛区域,而 ActivityKit 负责开启、更新和结束活动3。实时活动里的按钮,又一次,是 App Intents,因此灵动岛中的“暂停”或“下一首”控件运行的,和小组件按钮是同一类 intent。
让实时活动自成一门学问的,是它的更新路径。本地更新的计时器很简单。而一项由服务器上发生的事件(一份外卖在移动、一场比赛比分在变化)驱动的活动,则通过推送更新:您注册 pushTokenUpdates,从后端发送 ActivityKit 推送负载,系统便会在您的应用完全没有运行的情况下更新锁屏和灵动岛3。这确实强大,也确实极易出错,因为此时您活动的正确性取决于一份服务器契约、推送的可靠性,以及一套过期日期策略,而不再只是本地代码。
iOS 26 究竟改了什么
iOS 26 小组件的头条是呈现,而非架构。小组件采用了 Liquid Glass 材质,并获得强调色渲染模式,从而契合系统的全新设计语言,并在操作系统重新着色内容的场景中正确染色4。这对小组件在主屏幕、锁屏和待机显示中的观感很重要,值得做一轮设计打磨。但它并不改变交互的工作方式。如果您在 iOS 18 上构建过交互式小组件和控件,那 iOS 26 这一步是一次视觉焕新,而非重写。对于声称 iOS 26“引入”了交互式小组件的说法,请保持警惕;交互能力随 iOS 17 发布,控件随 iOS 18 发布,而 iOS 26 让它们看起来和系统其余部分浑然一体。
不过,Liquid Glass 带来的设计含义是真实存在的。小组件是系统叠合在壁纸之上、并透过玻璃质感外观折射的内容,因此与应用中的 Liquid Glass 一样的规则在此适用:尊重功能层与内容层的分层,不要用玻璃读不出来的厚重自定义背景去对抗这种材质。
把架构直白地说清楚
这才是值得记住的模型。一个 App Intent 是一项具名、有类型、有描述的能力。iOS 给了您一组不断增多的场所来挂载这项能力:
- 小组件内的
Button或Toggle。 - 控制中心、锁屏和操作按钮上的
ControlWidget。 - 实时活动及其灵动岛内的按钮。
- 一句 Siri 短语和一个快捷指令操作。
- 一项 Apple Intelligence 可代表用户调用的操作5。
上述每一处,都是同一个带有 perform() 方法的 AppIntent 类型。功夫在于把那项能力设计好:一个清晰的名称、有类型的参数、一个快速且幂等的 perform(),以及一个合理的结果。把这件事做好一次,那些表面就只是包装。这与我此前关于 App Intents 是通往您应用的真正 API的论述,以及关于如今一个 iOS 应用所暴露的三个表面的论述,是同一个道理:小组件表面不是您去构建的功能,而是您的能力一旦存在便会现身的场所。
何时不必费这个劲
小组件表面会回报那些真正拥有可一眼掌握的状态和快捷操作的应用:一个追踪器、一个计时器、一个开关、一个正在播放控件。它不会回报一切。
- 没有可一眼掌握的状态,就别做小组件。 如果您的应用没有任何不打开就值得展示的东西,那小组件就是装饰品,它只会给您带来维护成本和一个额外的扩展目标。
- 繁重或缓慢的操作不属于这里的
perform()。 小组件和控件的执行环境是受限的。如果操作需要真正的时间或真正的算力,那个按钮就该打开应用、进入一个准备好的状态,而不是假装在扩展里把活干完。 - 为并非“实时”的东西做实时活动。 实时活动是为有时限、正在主动变化的事件准备的。把它当作常驻的状态徽章使用,是对这一表面的误读,也是一条迅速进入系统“黑名单”、断送活动预算的捷径。
这门手艺不在于学会三种 API。而在于设计出值得挂载的 App Intents,再把它们挂到用户本就身处之地:他们会查看的主屏幕、他们会滑出的控制中心、那个已经在向他们展示着什么的灵动岛。把能力用心构建一次,iOS 便会把那些表面免费交到您手上。
常见问题
iOS 26 引入了交互式小组件吗?
没有。交互式小组件随 iOS 17 发布,控制中心控件随 iOS 18 发布;iOS 26 让它们采用 Liquid Glass 材质和强调色渲染,从而契合系统设计语言4。对于声称 iOS 26“引入”交互式小组件的说法请保持警惕:iOS 26 的变化是一次视觉焕新,而非重写。
iOS 小组件里的按钮究竟是如何完成工作的?
按钮运行的是一个 App Intent。小组件中的 Button 或 Toggle 会调用一个具名、有类型、带 perform() 方法的 AppIntent,因此小组件无需打开应用便可执行操作。同一个 intent 还驱动控制中心控件、实时活动按钮、Siri 短语和快捷指令操作5。
iOS 26 究竟为小组件改了什么?
是呈现,而非架构。小组件采用 Liquid Glass 并获得强调色渲染模式,从而在主屏幕、锁屏和待机显示中正确染色4。交互的工作方式与 iOS 18 上完全一致,所以一个已有的交互式小组件需要的是一轮设计打磨,而非重写。
应用没在运行时,实时活动是如何更新的?
通过推送。您注册 pushTokenUpdates,从后端发送 ActivityKit 推送负载,系统便会在您的应用没有运行的情况下更新锁屏和灵动岛3。这让活动的正确性取决于一份服务器契约、推送的可靠性,以及一套过期日期策略,而不只是本地代码。
一个 App Intent 能出现在哪些地方?
同一个 AppIntent 类型可挂载于小组件的 Button/Toggle、控制中心 / 锁屏 / 操作按钮上的 ControlWidget、实时活动及其灵动岛、一句 Siri 短语、一个快捷指令操作,以及作为一项 Apple Intelligence 可调用的操作5。把能力设计一次,那些表面就只是包装。
我什么时候不该做小组件或实时活动?
当应用没有任何不打开就值得展示、可一眼掌握的状态时,跳过小组件。在受限的小组件环境中,把繁重或缓慢的操作挡在 perform() 之外;改为打开应用、进入一个准备好的状态。另外,不要把实时活动当作常驻状态徽章用;它们是为有时限、正在主动变化的事件准备的,滥用一个就会烧掉您的活动预算。
-
Apple Developer, “Adding interactivity to widgets and Live Activities”. Interactive widgets (iOS 17+) use SwiftUI
Button(intent:)andToggle(isOn:intent:)backed by anAppIntent(orSetValueIntentfor toggles); the intent’sperform()runs in the widget extension without launching the app, and the timeline reloads to reflect the result. ↩↩↩↩ -
Apple Developer, “Creating controls to perform actions across the system” and the
ControlWidgetprotocol. Controls (iOS 18+) are built fromControlWidgetButtonandControlWidgetTogglewired to App Intents, and surface in Control Center, on the Lock Screen, and on the Action button. ↩↩↩ -
Apple Developer, “ActivityKit” and “Displaying live data with Live Activities”.
ActivityAttributesandActivityConfigurationdefine and render the Lock Screen and Dynamic Island; ActivityKit starts, updates, and ends activities, and server-driven updates use push withpushTokenUpdates. ↩↩↩↩ -
iOS 26 widget rendering: widgets adopt the Liquid Glass material and the accented rendering mode, controlled through
WidgetRenderingModeand the\.widgetRenderingModeenvironment value. The interactivity model (App Intents in widgets and controls) is unchanged from iOS 17 (widgets) and iOS 18 (controls). Apple, “WWDC 2025: the new software design” and the WidgetKit documentation. ↩↩↩↩ -
Apple Developer, “App Intents”. The same
AppIntenttype is the unit the system exposes through Siri, Shortcuts, Spotlight, the widget and control surfaces, and Apple Intelligence. Author’s analysis of the cross-surface model: App Intents Are Apple’s New API to Your App, App Intents 2 and the iOS 26 additions, and the three surfaces of an iOS app. ↩↩↩