使用 SwiftUI 为 iOS16 实现锁屏小组件
· 阅读需 5 分钟
iOS 要求最多的功能之一是可定制的锁屏。最后,我们在最新的iOS 16上得到了它。我们可以用一目了然的小组件填充我们的锁屏。实现锁屏小组件很简单,因为它的API与主屏幕小组件共享相同的代码。下面我们将学习如何为我们的应用程序实现锁屏小组件。
让我们从应用程序中可能已有的用于显示主屏幕小组件的代码开始。
struct WidgetView: View {
let entry: Entry
@Environment(\.widgetFamily) private var family
var body: some View {
switch family {
case .systemSmall:
SmallWidgetView(entry: entry)
case .systemMedium:
MediumWidgetView(entry: entry)
case .systemLarge, .systemExtraLarge:
LargeWidgetView(entry: entry)
default:
EmptyView()
}
}
}
在上面的示例中,我们有一个定义小组件的典型视图。我们使用环境来了解小组件系列,并显示适当大小的视图。为了支持锁屏小组件,我们只需要删除默认语句,并实现所有定义锁屏小组件的新情况。
struct WidgetView: View {
let entry: Entry
@Environment(\.widgetFamily) private var family
var body: some View {
switch family {
case .systemSmall:
SmallWidgetView(entry: entry)
case .systemMedium:
MediumWidgetView(entry: entry)
case .systemLarge, .systemExtraLarge:
LargeWidgetView(entry: entry)
case .accessoryCircular:
Gauge(value: entry.goal) {
Text(verbatim: entry.label)
}
.gaugeStyle(.accessoryCircularCapacity)
case .accessoryInline:
Text(verbatim: entry.label)
case .accessoryRectangular:
VStack(alignment: .leading) {
Text(verbatim: entry.label)
Text(entry.date, format: .dateTime)
}
default:
EmptyView()
}
}
}
最好记住,系统对锁屏和主屏幕小组件使用不同的渲染模式。该系统为我们提供了三种不同的渲染模式。
- 主屏幕小组件的 Full-color 模式和支持颜色的watchOS复杂功能。是的,您也可以使用WidgetKit实现watchOS复杂功能,从watchOS 9开始。
- Vibrant 模式是系统将文本、图像和仪表分解为单色,并为锁屏背景正确着色。
- Accented 模式仅在 watchOS上使用,系统将小组件分为两组,默认和重音。系统会用用户在表盘设置中选择的色调颜色为小组件的重音部分着色。
渲染模式可以通过 SwiftUI 环境获得,因此您可以随时检查哪种渲染模式处于活动状态,并将其反映在您的设计中。例如,您可以使用具有不同渲染模式的不同图像。
struct WidgetView: View {
let entry: Entry
@Environment(\.widgetRenderingMode) private var renderingMode
var body: some View {
switch renderingMode {
case .accented:
AccentedWidgetView(entry: entry)
case .fullColor:
FullColorWidgetView(entry: entry)
case .vibrant:
VibrantWidgetView(entry: entry)
default:
EmptyView()
}
}
}
如上例所示,我们使用小组件渲染模式环境值来获取实际渲染模式并做出不同的行为。正如我之前所说,在重音模式下,系统将您的小组件分为两部分,并专门为它们着色。您可以使用小组件可重音视图修饰符标记视图层次结构的一部分。在这种情况下,系统将知道哪些视图应用色调颜色。
struct AccentedWidgetView: View {
let entry: Entry
var body: some View {
HStack {
Image(systemName: "moon")
.widgetAccentable()
Text(verbatim: entry.label)
}
}
}
