大多数浏览器和
Developer App 均支持流媒体播放。
-
更新你的 App 至 watchOS 10
和我们一起更新 Apple Watch App,充分利用 watchOS 10 的最新功能。我们将会向你展示如何利用最新版 SwiftUI API 让信息一目了然,以及如何围绕数码表冠重新调整 App 浏览方式。
章节
- 1:33 - Build against the watchOS 10 SDK
- 2:33 - NavigationSplitView
- 5:21 - TabView and vertical pagination
- 8:11 - Toolbar with new placement options
- 9:07 - Background color
- 11:10 - Materials
资源
相关视频
WWDC23
-
下载
♪ ♪
Nina:大家好 我是 Nina Paripovic 一名 watchOS 软件工程师 在本次一起编程讲座中 我们将会使用 watchOS 9 SDK 编译的现有 App 更新至 watchOS 10 并一同探讨新的设计范例 以及在对系统进行全面重新设计时 可以让 App 更加美观的 SwiftUI API 示例项目已经链接在 与本次讲座相关的资源列表中 我建议你现在就开始下载 这样我们可以一同做好准备 为 watchOS 10 进行编译 在开始之前 我们先来看一下现有项目 我们所要更新的 App 是 Backyard Birds 在这款 App 中 你可以创建并管理美丽的后院花园 以及对其充满好奇的访客 现在 该 App 有一个后院 List 每个后院都有一个详细信息视图 向我们展示后院中的活动和状况 如果食物量或水量不足 你可以进行补充 我们还可以在每个后院中 看到所有鸟类访客 watchOS 10 为手表 App 带来了令人兴奋的全新外观 如果你还没有使用 watchOS 10 欢迎收看“认识 watchOS 10” 以及“为 watchOS 10 设计并编译 App” 以获得本次讲座即将应用的 设计原则 现在 让我们打开 Xcode 从更新 App 开始
这就是当前我们使用 watchOS 9 编译并运行的 Backyard Birds App 可以看到 这里是一个后院 List 跳转后会显示后院详细信息 首先 我们来使用 watchOS 10 SDK 进行编译
这款 App 看起来已经很棒了 我们可以看到一些新系统功能 例如 会随着滚动转换的大标题 以及用于虚化导航栏 下方内容的新材质 轻点后院 该单元便会出现动画效果 然后我们就可以在左上角看到 整个系统的工具栏按钮 如果我们滚动并轻点补充 就可以看到使用全新 虚化背景材质的模态
Backyard Birds 的用户 对自己后院所发生的事 最为关心 所以 他们现在只要启动 App 第一件事就是轻点 List 中的后院 并在详细信息视图中查看当前状况 在 watchOS 10 中 我们利用 NavigationSplitView 修改 App 架构以简化该过程 从而 用户不仅可以 直接启动后院详细信息视图 并且在希望访问朋友的后院时 能够跳转回到 List 由于详细信息视图是该 App 最重要的功能之一 因此 我们可以使用 NavigationSplitView 来突出该功能
如果我们拥有强大的源 List 以及详细信息关系 NavigationSplitView 便可以发挥优势 这样用户不仅可以在启动后 直接看到详细信息 同时还能够从源 List 中 轻松切换到另一个后院
iOS 和 iPadOS 中的 Backyard Birds 均已使用该技术 看起来 NavigationSplitView 非常适用于该 App
所以在 ContentView 中 我们会将 NavigationStack 替换为 NavigationSplitView 接着 将 navigationDestination 的内容 移动到 NavigationSplitView 的详细信息中 最后 采用 watchOS 10 中 新的 List 选项 API 驱动 NavigationSplitView 显示的详细视图 首先 我们从使用 NavigationSplitView 替换 NavigationStack 开始
我们可以将 Backyard List 保留在 NavigationSplitView 根目录中 然后移除 navigationDestination 修饰符 并将 BackyardView 移动到详细信息视图构建器中 由于 selectedBackyard 是一个可选项 因此我们需要对其进行解包 并提供回退视图
最后 使用接受可选绑定的 List 初始化器 如果你对 List 中的 selection 参数进行赋值 该可选绑定就会驱动 在 NavigationSplitView 中 显示的详细信息视图
很好 现在 我们可以看到默认情况下 所选后院的详细信息视图 由于启动后可以直接看到详细信息 所以我们将 navigationTitle 移除 使用源 List 按钮 我们便可以导航返回 以查看其他后院 轻点返回到详细信息视图 我们则可以看到漂亮的全屏动画 当前 后院视图是 由可滚动内容构成的长 List 我们将其分为三个具有不同 功能集的部分 今日视图、习性视图 以及访客视图 利用 TabView 并为每个部分创建标签页 我们便可以带来 更为清晰的视觉体验
TabView 可以将内容 分为全屏视图 并且每个标签页都具有 清晰且独特的用途 如果我想保留数码表冠功能 以便快速滚动视图 新的垂直页面样式便可以 在 TabView 中实现这一点 用户不仅可以在标签页间快速导航 甚至还可以滚动单独的标签页
让我们回到 Xcode 更新详细信息视图 将 TabView 运用其中
在 BackyardView 中 我们将每个部分移到 各自的视图中 并将 List 替换为 TabView 由于 TabView 的每个页面 均为全屏显示 所以我们不需要 Section 和 Divider 但我们需要将各部分的标题 添加回来 并作为 navigationTitle
最后 使用 tabViewStyle 修饰符 指定我们想要的 verticalPage 这样我们就快完成了 使用分页功能 我们便可以 看到每个标签页的视图 为了方便用户快速查看所有的访客 我们将 VisitorView 封装进一个 List 中
现在 TabView 便可以为其 每个子 List 视图指定一个标签页 如果 List 超出了屏幕高度 视图便可以滚动
如果你在垂直 TabView 中 存在需要滚动的内容 尽可能将其放置于 最后一个标签页中
接下来 我会将习性视图 分为两个单独的标签页 以便用户可以轻松区分 食物和水所对应的信息
为此 我在 TabView 中 创建了一个更为合适的仪表盘
并使用新的 GaugeView 替换 HabitatView 分别为食物和水创建一个实例
这样看上去就很不错 现在 我们只需要 将补充功能添加回来就可以了 我会使用工具栏来实现这一步 watchOS 10 中的工具栏 经过升级 具备了全新的位置选项 并且 可以在所有屏幕尺寸中保持一致 新的底部栏位置 是放置控件的不错选择 因此我会使用该位置选项 并将填充按钮添加到底部栏中
回到新的 HabitatGaugeView 中 添加一个工具栏 然后使用 ToolbarGroup 指定想要的底部栏位置 接着 使用 Spacer 将按钮添加到工具栏的尾部
这样显示的空间就更大了 习性摘要也会更加一目了然 此外 我还想帮助用户 在 TabView 间导航时进行定位 并在后院食物量和水量不足时 提醒用户 使用渐变背景便可以实现这一点 尽管为每个标签页设置标题也有用 但使用颜色可以更加一目了然 并且能够强调 我们在详细信息视图中的状态 同时 我们还可以在食物量 和水量不足的情况下 突出后院的状态 系统渐变是一个传达该信息 的不错方法 同时能够与前景元素 保持良好的对比度 接下来 让我们使用容器背景修饰符 以及颜色渐变来实现这一点 首先 我们需要移除原始背景 接着在 BackyardView 中 添加可根据当前食物量和水量 决定颜色的函数 如果食物量和水量不足 背景就会变为红色 表示是时候进行补充了 另外 我还会添加一些有用的计算变量 并将计算属性传递给 containerBackground 修饰符
修饰符会接受 ShapeStyle 并且我们会向 ShapeStyle 中传递颜色渐变 以及 ContainerBackgroundPlacement 在这里 我们指定其用于 TabView
另外 我还希望在背景改变时 改变仪表盘颜色 为此 我们可以 传递相同的计算颜色变量
并利用 App 强调色 将 containerBackground modifier 修饰符 应用到 TabView 的其他视图中
当我们进行滚动时 你便可以看到 渐变色与前景元素之间 形成了良好的对比 再轻点工具栏按钮 我们还可以看到 渐变背景是如何变化的
最后 我还想利用 Materials 来强调重要信息 Materials 目前可跨平台使用 并且也是 watchOS 10 中 watch App 的新增功能
这些功能不仅可以有效区分 前景与背景中的元素 同时还可以增强视觉效果 最重要的是 还能够 在屏幕上显示或强调信息 Materials 和 Vibrancy 可以用于 App 中的几个地方 让我们来看一下 首先 我会使用材质背景 替换后院标题的阴影背景 由于单元背景是彩色的 添加材质可以让 标题更加清晰
用户十分关心每个后院中 鸟类访客的数量 而该内容 需要在摘要视图中进行查看 如果可以用 List 视图 来显示就更好了 这样用户无需进入后院的 详细信息视图便可看到该信息 在这里 我还会增加另一个覆盖层 并为数字添加材质背景 watchOS App 通常使用深色背景 因此材质默认为 dark 变体 由于后院是明亮多彩的 所以我会将其切换为 light 变体
至此 我们已经完成了 Backyard Birds App 针对 watchOS 10 的更新
让我们回顾一下 刚刚完成的重大更改 首先 我们将 NavigationSplitView 添加到 List 中 接着 使用垂直 TabView 替换了 List 并为每个后院的工具栏 增加了功能 以及漂亮的渐变色 最后 我们还利用 Materials 来显示实用信息 感谢你和我一起进行编码 今年是 Apple Watch 重要的一年 期待你进一步探索更多讲座内容 若想了解更多有关 Backyard Birds 的信息 欢迎观看 “在 Apple Watch 智能叠放上构建小组件” 我非常期待看到你的更新 并希望你的 App 可以在 watchOS 10 中大放异彩
-
-
4:02 - NavigationSplitView
NavigationSplitView { List(backyardsData.backyards, selection: $selectedBackyard) { backyard in BackyardCell(backyard: backyard) } .listStyle(.carousel) } detail: { if let selectedBackyard { BackyardView(backyard: selectedBackyard) } else { BackyardUnavailableView() } }
-
6:18 - Vertical TabView
TabView { TodayView() .navigationTitle("Today") HabitatGaugeView(level: $waterLevel, habitatType: .water, tintColor: .blue) .navigationTitle("Water") HabitatGaugeView(level: $foodLevel, habitatType: .food, tintColor: .green) .navigationTitle("Food") List { VisitorView() .navigationTitle("Visitors") } } .tabViewStyle(.verticalPage)
-
8:37 - Add refill button to Toolbar
.toolbar { ToolbarItemGroup(placement: .bottomBar) { Spacer() Button { level = Int(min(100, Double(level) + 5)) } label: { Label("Add", systemImage: "plus") } } }
-
9:48 - HabitatGaugeView background color function and variables
func backgroundColor(_ level: Int, for type: HabitatType) -> Color { let color: Color = type == .food ? .green : .blue return level < 40 ? .red : color } var waterColor: Color { backgroundColor(waterLevel, for: .water) } var foodColor: Color { backgroundColor(foodLevel, for: .food) }
-
10:10 - .containerBackground within TabView
TabView { TodayView() .navigationTitle("Today") .containerBackground(Color.accentColor.gradient, for: .tabView) HabitatGaugeView(level: $waterLevel, habitatType: .water, tintColor: waterColor) .navigationTitle("Water") .containerBackground(waterColor.gradient, for: .tabView) HabitatGaugeView(level: $foodLevel, habitatType: .food, tintColor: foodColor) .navigationTitle("Food") .containerBackground(foodColor.gradient, for: .tabView) List { VisitorView() .navigationTitle("Visitors") .containerBackground(Color.accentColor.gradient, for: .tabView) } } .tabViewStyle(.verticalPage) .environmentObject(backyard) .navigationTitle(backyard.displayName)
-
11:38 - Add material to the backyard name
.foregroundStyle(.secondary) .background(Material.ultraThin, in: RoundedRectangle(cornerRadius: 7))
-
12:15 - Visitor score overlay with materials
.overlay(alignment: .topTrailing) { Text("\(backyard.visitorScore)") .frame(width: 25, height: 25) .foregroundStyle(.secondary) .background(.ultraThinMaterial, in: .circle) .padding(.top, 5) }
-
12:20 - Light materials
.environment(\.colorScheme, .light)
-
-
正在查找特定内容?在上方输入一个主题,就能直接跳转到相应的精彩内容。
提交你查询的内容时出现错误。请检查互联网连接,然后再试一次。