在 SwiftUI 中创建复杂功能

722次阅读  |  发布于4年以前

概述

这个主题主要是讲述了如何使用 SwiftUI 来编写手表表盘上的小组件,展示了使用 SwiftUI 为开发者带来的强大与便捷。

复杂组件

Complications 是在 Apple Watch 表盘上显示 App 详细内容的组件,下图列举了复杂组件的一些形态。现在 SwiftUI 提供了一系列更便捷的 API 来打造 Watch App 的复杂组件。SwiftUI 还提供了多种表盘模板,帮助快速检查复杂组件在不同表盘形态下的不同表现。

新的 API

文本组件

默认的字体会随着组件的大小的变化而变化,Text 组件还提供了不同的日期格式化方式,特别是提供了相对时间的格式化方式,如下图。

示例代码:

Text(date, style: .relative)
Text("Time remaining: \(timer.startDate, style: .timer)")

进度视图和仪表

Progress View 进度条视图是左边的样式,用来展示跟进度相关的信息,SwiftUI 中对应为 ProgressView,进度条视图提供了圆形的样式和线性的样式,使用方式可以参考示例代码。

ProgressView(value: 0.7) {
    Image(systemName: "music.note")
}
.progressViewStyle(CircularProgressViewStyle(tint: .red))
//.progressViewStyle(LinearProgressViewStyle(tint: .red))

Gague 是右边的样式,提供了一种展示当前数值的图表,可以自定义的参数有最小最大值,当前数值,图标,渐变色等,使用方式参照下面等示例代码:

Gauge(value: acidity, in: 3...10) {
    Image(systemName: "drop.fill")
        .foregroundColor(.green)
} currentValueLabel: {
    Text("\(acidity, specifier: "%.1f")")
} minimumValueLabel: {
    Text("3")
} maximumValueLabel: {
    Text("10")
}
.gaugeStyle(
    // LinearGaugeStyle( // 同时还提供了线性的样式
    CircularGaugeStyle(
        tint: Gradient(colors: [.orange, .yellow, .green, .blue, .purple])
    )
)

表盘表面着色

本节介绍表盘的主题色,因为 Apple Watch 表盘提供了许多主题色,如全彩,橘红等等,所以在编写自己的复杂组件时,要注意复杂组件在主题色变化时的表现。复杂组件的在主题色变化时会有几种处理方式,Full Color 全彩,复杂组件在这种模式下颜色全部展示;Desaturated 去饱和,去除颜色的饱和度,来使组件主题色与表盘保持一致;Color opacity 不透明颜色,下文会仔细说明。

去饱和

去饱和方式时系统的默认处理方式,当表盘使用主题色的时候,系统会将组件灰阶化,然后再使用主题色进行渲染。因为有灰阶化的处理,所以注意不要选择使用亮度相近的颜色,否则在灰阶化处理后,元素颜色过于相近而无法区分。最后推荐在编写复杂组件时,在去饱和模式下检查一下内容是否正确。

颜色不透明度

这是系统提供的另外一种主题色处理方式,这种方式需要在构建视图时存在不同的视图层,这样在主题色变化时,系统会根据不同的层给予不同的颜色。因为复杂组件的视图层一般有背景和内容两类,所以需要使用 .complicationForeground() 来指定某一个视图为主视图。使用方式如下:

var body: some View {
    ZStack {
        Circle()
            .fill()
        Image("apple")
            .foregroundColor(.yellow)
            .complicationForeground()
    }
}

高级自定义

SwiftUI 更进一步提供了 ComplicationRenderingMode 来做进一步定制。该值可以从环境中取出,可以根据此值,实现在不同的模式下的不同表现。

下面的代码实现了在主题色模式下使用渐变的背景色:

预览

在 SwiftUI 的 Preview 中,提供了下列一系列的预览方式来检查复杂组件的表现:

下面的代码演示了如何使用上面的 API 来预览:

最佳实践

  1. 点击复杂组件一定会启动 App
  2. 使用 Text,Image,绘制请使用基础组件,如 Shapes,Paths,Paints
  3. 不支持 SwiftUI 的动画
  4. 每一次展示视图时,都会检测相关的性能,注意性能
  5. 使用合适大小的图片
  6. 限制开销大的绘制,如模糊和格式化字符串
  7. 注意 Xcode 给出的 Runtime 警告
  8. 依据默认的字体大小来指导布局
  9. Rectangular Full View 使用 safe area 布局(可以使用 .edgesIgnoreingSafeArea()忽略 safe area)

总结

复杂组件的存在就是让用户在表盘上能一眼瞟到他关心的内容,本身就不是很复杂。SwiftUI 的加入,也可以大大降低此类组件的编写成本。现在在 watchOS 7 中添加了表盘分享能力,可以为你的 APP 定制表盘分享,当用户接受表盘并且在手表上没有安装相应 app 时会自动下载,也提供了一种分发 APP 的新方式。

相关视频

Build Complications in SwiftUI: https://developer.apple.com/videos/play/wwdc2020/10048/ Create Complications for Apple Watch: https://developer.apple.com/videos/play/wwdc2020/10046/ Keep Your Complications Up to Date: https://developer.apple.com/videos/play/wwdc2020/10049/

Copyright© 2013-2020

All Rights Reserved 京ICP备2023019179号-8