说说 iOS 16 的锁屏 Widget

swift 发布于 2022年12月04日

iOS 16 正式发布了, 我也第一时间在设备上更新了。 和大家聊聊锁屏 Widget。

如何使用

锁屏 Widget,和 iOS 14 推出的桌面 Widget 一样, 都属于 WidgetKit 提供的能力。 只需要在原有的 Widget 实现代码中,加入新的 Families 支持,即可实现。比如以往的 Widget 代码中需要通过如下声明来告诉系统我们的 App 支持哪些尺寸的 Wideget:

.supportedFamilies([.systemSmall, .systemMedium, .systemExtraLarge])

iOS 16 又提供了 3 个新的 Family:.accessoryCircular, .accessoryRectangular, .accessoryInline。 这三个类型分别对应在锁屏状态下,3种不同的 Widget 类型。

加入这三个 Family 即可即可开通锁屏 Widget 的支持:

.supportedFamilies([.systemSmall, .systemMedium, .systemExtraLarge, .accessoryCircular, .accessoryRectangular, .accessoryInline])

用户层面,在锁屏状态下长按主屏幕,就会展示编辑按钮:

点击按钮之后, 我们可以在两个位置放置锁屏 Widget, 第一个是屏幕顶部:

这个位置是 .accessoryInline 对应的类型,一般在这里显示一部分文字信息。并且这行开始的日期文本应该是不能取消掉,比如我们这张图片中的 "Wed 14" 文字。默认行为是这样,我们自定义的 Widget 在这里无法替换掉左边的日期内容,至于有没有方法强制让这个日期文字隐藏,我还没有深入去看文档。但至少从产品体验角度来说,如果你的 Widget 本身不能显示日期,那么系统的日期文字就不应该隐藏。

另外一个位置就是时间文字下方的一行:

从上图中我们可以看到,这个区域我们放置了 3 个 Widget, 第一个 Widget 占据了两个单元格空间, 另外两个分别占用一格子。 也就是说,用户的锁屏中,最多能放 4 个 Widget(因为只有 4 个格子,最小的 Widget 也会占用 1 个格子)。

占用两格空间的 Widget 对应的是 .accessoryRectangular, 只占用一格的 Widget 对应的是 .accessoryCircular

产品分析

上面两张图,让我们对锁屏 Widget 有了一个初步的了解。 首先,最主要的认识就是,它的入口非常有限。 算上顶部 1 个位置, 以及中间的最多有 4 个位置, 一台设备上锁屏 Widget 最多只能放 5 个。

这点和桌面 Widget 不同,虽然实践上来看,一个用户也不会使用过多的桌面 Widget,但毕竟它在技术层面是不限制数量的。锁屏 Widget 从技术定义上就已经限定好了,最多 5 个位置。

虽然这个入口位置很少,但是它确实能很大的改变用户通过 iPhone 和每一个 App 的交互的方式。尤其是新版 iPhone 设备中 Always On Display 屏幕常亮的加入。要知道在以前很长的时间,能直接从锁屏打开的应用就只有两个,相机和手电筒。而现在,苹果把这个能力开放给了每一个开发者。

技术实现

从开发角度来看,锁屏 Widget 和之前的桌面 Widget 差别并不大。 首先就是你需要支持几个新的 Family 类型, 前面也提到过, .accessoryCircular, .accessoryRectangular.accessoryInline

并且对这几个 Family 类型提供相应的 View:

struct CustomView: View {
var entry: Provider.Entry

@Environment(\.widgetFamily) var family // 当前对应的 family

@ViewBuilder
var body: some View {
switch family {
case .accessoryInline:
// 为 Inline 类型的锁屏 Widget 返回 相应的 View
case .accessoryRectangular:
// 为 Rectangular 类型的锁屏 Widget (也就是占用两格)返回 相应的 View
case .accessoryCircular:
// 为 Circular 类型的锁屏 Widget (占用1格)返回 相应的 View
case .systemSmall:
...
}
}

如果你已经对桌面 Widget 开发比较熟悉的话,真的没有太多可说的了。 如果没有接触过 Widget 开发的话, 可以参考官方文档:https://developer.apple.com/documentation/widgetkit/creating-a-widget-extension

或者看一下我之前写的关于 widget 入门的内容(因为是2年前写的,我不保证里面的内容和现在的 SDK 是否完全一致,所以如果英文阅读还可以的话直接看官方文档最好)。

代码复用

如果一定要找一些变化说一下的话,就是这三个新的 Family,同时支持 watchOS, 并且 watchOS 还提供了另外一个专属的 Family,就是 .accessoryCorner。也就是说 iOS Widget 对应的这 3个 Family 的代码可以在 watchOS 上面复用。

渲染模式

另外, iOS 16 对 Widget 新加入了渲染模式的环境变量:

@Environment(\.widgetRenderingMode) var widgetRenderingMode

大家从前面的截图中可能也注意到了,锁屏 Widget 的整体颜色是和锁屏界面上的时间文字一致的。我们无法自己决定锁屏 Widget 的颜色, 这点和桌面 Widget 不一样。 在 iOS 16 中,用户还可以自行修改这个颜色:

WidgetKit 会通过这个环境变量来告诉我们当前 Widget 的渲染模式是什么,我们就可以做出相应的判断:

var body: some View {
ZStack {
switch renderingMode {
case .fullColor:
// 全彩模式, 这时候 Widget 可以使用任意颜色
case .accented:
// 这个是 watchOS 专属的渲染模式,这里不多讲解
case .vibrant:
// 锁屏 Widget 的渲染模式,我们 Widget 的颜色会根据用户的选择来决定
}
}

通用背景

新的 Widget SDK 提供了一个, AccessoryWidgetBackground UI 组件,用于给桌面 Widget 以及 watchOS 对应的 Widget 提供一个通用的背景色, 这个背景色会随着用户调节的颜色而改变,比如我们这张图所示:

实现起来也很简单,就是把它加入我们的 View 代码中:

ZStack {
AccessoryWidgetBackground()
...
}

要不要使用这个背景组件,就根据我们自己产品的实际情况来决定吧。

写在最后

总的来说,锁屏 Widget 给开发者算是提供了一个新的机会。 这里就是简单的把它的特性,限制条件和大家分享一下。如果有更多时间的话,大家可以去看一下官方的文档,里面有更详细的讲述:https://developer.apple.com/documentation/widgetkit/creating-a-widget-extension

因为我订的 iPhone 14 还没有到货,现在还没办法在真机上了解 Widget 和灵动岛交互的相关细节。从技术细节上来说,新的 WidgetKit 并没有增加太多内容,如果你比较熟悉之前的桌面 Widget 开发,基本上可以直接上手。

我的建议,你或者你团队的产品, 在可能的情况下尽量加入这个 Widget 的能力,至少在这个阶段这些 App 会更容易被 App Store 推荐, 比如现在就有一个专题在推荐相关的 App:

这也是 App Store 的一个常用方式了, 每次 iOS 推出一些新的能力时,就会推荐一些支持它最新特性的 App。 即便你的 App 没有被这个专题推荐,在一些其他方面肯定也会有一个比较好的权重。关于 App 运营的内容,其实也有不少可以和大家聊的。

篇幅有限,大家的阅读时间也有限,这些就先说这么多,希望对你有用。


如果你觉得这篇文章有帮助,还可以关注微信公众号 swift-cafe,会有更多我的原创内容分享给你~

本站文章均为原创内容,如需转载请注明出处,谢谢。
关注微信公众号
发现更多精彩
swift-cafe