SwiftUI 新特性 - WWDC22
type
status
date
slug
summary
tags
category
icon
password
这个 session 主要介绍了 swiftUI 相关的新特性。
参考文档:
- Food Truck: Building a SwiftUI multiplatform app 一套代码适配 Mac、iPad 和 iPhone 的官方示例
今年的 swiftUI 又新增了很多新的特性和功能,如果想要开始学习使用 swiftUI,现在是比较好的时机,用来开发简单的 app 已经没有什么问题,但是要用在正式的项目中还是得慎重。下面我分别介绍下 swiftUI 的新特性。
Swift Charts
目前 iOS 如果想要绘制图表,我第一个想到的应该是 github 上排第一的 GitHub - danielgindi/Charts,底层使用 CoreGraphics,非常强大,但是缺点是对 Accessibility 支持有限。苹果新推出的 Swift Charts 可视化数据,使用 SwiftUI 语法来创建,还可以使用 ChartRenderer 接口将图标渲染成图。
关于 Swift Charts,官方文档 Swift Charts,入门 Session: Hello Swift Charts,Apple 官方介绍 Creating a chart using Swift Charts。高级定制和创建更精细图表,可以看这个 Session: Swift Charts: Raise the bar,这个 session 也会提到如何在图表中进行交互。这里是 session 对应的代码示例 Visualizing your app’s data 。关于图表设计的 session,Design an effective chart 和 Design app experiences with charts 。
一些特性:
- 可以装载数据,BarMark 用于创建条形图,LineMark 用于创建折线图。PointMark、AxisMarks、AreaMark、RectangularMark 和 RuleMark 用于创建不同类型的图表。
- API 使用非常简单清晰,代码量非常少,对开发者很友好。
- 支持自动深色模式。
Navigation and windows
navigation bar 有新的默认行为,如果没有提供标题,导航栏默认为 inline title 显示模式。使用
navigationBarTitleDisplayMode(_:)
改变显示模式。如果 navigation bar 没有标题、工具栏项或搜索内容,它就会自动隐藏。使用 .toolbar(.visible)
modifier 可以显示一个空 navigation bar。Stacks
NavigationStack
是一个新的用于 push 和 pop 的导航栏容器。替代了 NavigationView
,现在使用新的数据驱动的 API .navigationDestination(for: ...)
,NavigationLink
现在可以传入代表目的地的值,不止如此,我们可以通过传入 path
给 NavigationStack
来实现控制导航控制器的堆栈。
新的导航方案废弃了 NavigationView
, 引入了 NavigationStack
和 NavigationSplitView
来实现导航功能。采用导航路径数据驱动视图的方式,而不再需要我们手动逐个管理 NavigationLink
的状态,成功地解决了导航路径状态难以管理的难题。与此同时,新方案提出了 NavigationLink
和目标视图分离的方案,解决了目标视图会被重复创建的诟病。Split Views
SwiftUI 为了方便在大屏上做分屏显示,提供了一个非常便利的分屏视图
NavigationSplitView
, 它能根据不同平台屏幕的尺寸把视图分两列或者三列显示。在小屏幕上显示时,自动折叠成单列。而 NavigationStack
即使在大屏上,也只是单列显示。其实也就是对应了 UIKit 中的 UISplitViewController
。参考:
Window
SwiftUI app 的结构是由 App, Scene 和 View 共同组成的统一的所有制层次结构。App 包含一个或多个 Scene,而 Scene 作为 View 的容器包含了很多的 View。Scene 是一个协议,我们目前最常用的 WindowGroup 就是符合 Scene 协议的 scene type,系统会根据 Scene type,平台特性及上下文以不同的方式调整 Scene 的展示行为, 可能会填满整个屏幕或部分屏幕等,在诸如 iPadOS 和 macOS 这样支持多窗口的平台上,一个 WindowGroup 可以包含多个相同类型的窗口。
现有的 Scene types。
- WindowGroup - 这个 Scene 提供了一种跨 Apple 平台的构建数据驱动 app 的方法;
- DocumentGroup - 可以在 iOS 和 macOS 上构建 document-based apps;
- Settings - 可以定义一个在 macOS 中进行应用设置的 Window。
这次新增了两个 scene types:
- Window,在 MacOS 上表示一个唯一的,单一的 Scene;
- MenuBarExtra,在 macOS 系统的菜单栏中呈现为常驻控件。
如果你的应用在 mac 上限制了只展示一个窗口,就可以使用新的 Window,例如游戏。
MenuBarExtra 这是显示在右上角状态栏下方的窗口,在 app 运行的时候显示,也可以单独提供一个 MenuBarExtra 做为主要的 scene 。
Advanced controls
Forms
新增
.formStyle(.grouped)
用来改进在 macOS 上的表单,今年 MacOS 的控制中心,字体册,还有系统设置的大部分都是使用 swiftUI 进行开发。Controls
TextField
和Text
可以限制行数,最小行和最大行。
MultiDatePicker
日期选择器支持多选。
- 使用
DisclosureGroup
将多个状态组合成一个,统一管理。
- Button Styles 现在支持应用到类似按钮外观的控件,包括 toggle, menu, 和 picker。
Stepper
新增 format 的能力,支持多种类型,例如百分比。现在也可以在 watchOS 上使用。
- SwiftUI 引入一个新显示进度的视图 Gauge。
Tables
Table
现在支持 iOS 和 iPadOS。
- 默认在 iOS 中只显示首列,性能和 List 差不多,估计只是为了兼容 MacOS 代码。
- 允许定义高级的上下文菜单。
- 在 iPadOS 上有新的 ToolBar,可以和 MacOS 一样自定义顶部 Toolbar。
Search
- 搜索框现在支持搜索字段,通过新的搜索修饰符。
.searchable
支持 token 和 scope。
Sharing
Photos Picker
- 支持图片选择器。
- 可以对选择的内容进行过滤和自定义。
Sharing
- 新的
ShareLink
API,来使用系统的分享功能,和UIActivityViewController
类似,可以针对多个平台自动适配。
- 使用
dropDestination
来接收外部传入的数据,支持String
,Data
,URL
,Attributed String
以及Image
等类型的数据。
- 只要遵循
Transferable
协议,其他类型的数据也可以传递。
Graphics and layout
ImageRenderer
可以将 SwiftUI 的 View 生成图片。
官方参考文档 ImageRenderer
SF Symbol
- SF Symbol 4.0 支持变量值,可以通过设置 variableValue 来填充不同部分,比如 wifi 图标,不同值会亮不同部分,
Image(systemName: "wifi", variableValue: 0.5)
。
- 并且新增了阴影和渐变,可以通过代码自定义。
Text
Text 现在可以在修改字重,风格还有布局的时候通过动画过渡,只需要使用
withAnimation
。Layout
- 新增了 Grid 视图,来同时满足 VStack 和 HStack,
Grid
提供了一种新的布局方式,不再局限于LazyVGrid/LazyHGrid
,开放了GridRow
与.gridCellColumns(count)
。
- 可以通过自定义
Layout
满足更多的布局要求,与 UIKit 中的自定义UICollectionFlowLayout
类似,遵循Layout
协议,提供每个元素所在位置,并且根据协议提供的子视图来返回父视图所需空间即可完成。相关使用:The Layout Protocol 。
ViewThatFits
允许根据适合的大小放视图。ViewThatFits
会自动选择对于当前屏幕大小合适的子视图进行显示。示例效果 ,对应示例代码 LayoutThatFits.swift。
总结
今年的 swiftUI 又是一次大的更新,很明显 apple 的重心正在往这种现代化布局框架迁移,但是有一说一,目前的稳定性还达不到正式在项目中使用的程度,况且 iOS16 的新特性如果要上线使用至少也要两年后。不过提前学习了解一定对将来有帮助。
- Giscus