【WWDC20】10048 - 在 SwiftUI 中创建复杂功能

2,340 阅读5分钟

使用 SwiftUI 在 Apple Watch 上增加图形复杂功能。我们将教你如何在 Meridian 和图文这种表盘的复杂功能上使用自定义 SwiftUI 视图,查看创建复杂功能的最佳方法,我们还将演示在 Xcode 12 中的成果预览。

作者: BluesJiang,iOS 开发者,目前就职于阿里巴巴,手淘 iOS 架构组。Github博客

Session: developer.apple.com/videos/play…

概述

这个主题主要是讲述了如何使用 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 的新方式。

相关视频

推荐阅读

限时福利

这篇文章的内容来自于 《WWDC20 内参》。在这里给大家推荐一下这个专栏。

「WWDC 内参」系列是由老司机周报、知识小集合以及 SwiftGG 几个技术组织发起的。已经做了几年了,口碑一直不错。主要是针对每年的 WWDC 的内容,做一次精选,并号召一群一线互联网的 iOS 开发者,结合自己的实际开发经验、苹果文档和视频内容做二次创作。

今年一共有 213 个 Session 的内容。《WWDC20 内参》挑选了其中的 135 个 Session,专栏现已创作了 97 篇文章。目前正在优惠销售,只需要 29.9 元,十分优惠。

看了文章还不过瘾的朋友,抓紧订阅 《WWDC20 内参》 https://xiaozhuanlan.com/wwdc20 继续阅读吧~

关注我们

我们开通了公众号「老司机技术周报」,每期发布时公众号(LSJCoiding)会推送消息,欢迎关注。