WWDC 23 之后的 SwiftUI 有哪些新功能

文章目录

    • 前言
    • 数据流
    • 动画
    • ScrollView
    • 搜索
    • 新手势
    • 新增的小功能
    • 总结

在这里插入图片描述

前言

WWDC 23 已经到来,SwiftUI 框架中有很多改变和新增的功能。在本文中将主要介绍 SwiftUI 中数据流动画ScrollView搜索新手势等功能的新变化。

数据流

Swift 5.9 引入了宏功能,成为 SwiftUI 数据流的核心。SwiftUI 不再使用 Combine,而是使用新的 Observation 框架。Observation 框架为我们提供了 Observable 协议,必须使用它来允许 SwiftUI 订阅更改并更新视图。

@Observable
final class Store {var products: [String] = []var favorites: [String] = []func fetch() async {try? await Task.sleep(nanoseconds: 1_000_000_000)// load productsproducts = ["Product 1","Product 2"]}
}

不需要在代码中遵循 Observable 协议。相反,可以使用 @Observable 宏来标记你的类型,它会自动为符合 Observable 协议。也不再需要 @Published 属性包装器,因为 SwiftUI 视图会自动跟踪任何可观察类型的可用属性的更改。

struct ProductsView: View {@State private var store = Store()var body: some View {List(store.products, id: \.self) { product inText(verbatim: product)}.task {if store.products.isEmpty {await store.fetch()}}}
}

以前,有一系列的属性包装器,如 StateStateObjectObservedObjectEnvironmentObject,你应该了解何时以及为何使用它们。

现在,状态管理变得更加简单。对于值类型(如字符串和整数)和符合 Observable 协议的引用类型,只需使用 State 属性包装器。

struct FavoriteProductsView: View {let store: Storevar body: some View {List(store.favorites, id: \.self) { product inText(verbatim: product)}}
}

在上面的示例中,有一个接受 Store 类型的视图。在之前的 SwiftUI 框架版本中,应该使用 @ObservedObject 属性包装器来订阅更改。现在不需要了,因为 SwiftUI 视图会自动跟踪符合 Observable 协议的类型的更改。

struct EnvironmentViewExample: View {@Environment(Store.self) private var storevar body: some View {Button("Fetch") {Task {await store.fetch()}}}
}struct ProductsView: View {@State private var store = Store()var body: some View {List(store.products, id: \.self) { product inText(verbatim: product)}.task {if store.products.isEmpty {await store.fetch()}}.toolbar {NavigationLink {EnvironmentViewExample()} label: {Text(verbatim: "Environment")}}.environment(store)}
}

还可以使用 Environment 属性包装器与 environment 视图修饰符配对,将可观察类型放入 SwiftUI 环境中。不需要使用 @EnvironmentObject 属性包装器或 environmentObject 视图修饰符。同样的 Environment 属性包装器现在适用于可观察类型。

struct BindanbleViewExample: View {@Bindable var store: Storevar body: some View {List($store.products, id: \.self) { $product inTextField(text: $product) {Text(verbatim: product)}}}
}

每当需要从可观察类型中提取绑定时,可以使用新的 Bindable 属性包装器。

动画

动画始终是 SwiftUI 框架中最重要的部分。在 SwiftUI 中轻松实现任何动画,但之前的框架版本缺少一些现在具有的功能。

struct AnimationExample: View {@State private var value = falsevar body: some View {Text(verbatim: "Hello").scaleEffect(value ? 2 : 1).onTapGesture {withAnimation {value.toggle()} completion: {print("Animation have finished")}}}
}

如上例所示,我们有了新版本的 withAnimation 函数,允许提供动画完成处理程序。这是一个很好的补充,现在您可以构建阶段性动画。

enum Phase: CaseIterable {case startcase loadingcase finishvar offset: CGFloat {// Calculate offset for the particular phaseswitch self {case start: 100.0case loading: 0.0case finish: 50.0}}
}struct PhasedAnimationExample: View {@State private var value = falsevar body: some View {PhaseAnimator(Phase.allCases, trigger: value) { phase inLoadingView().offset(x: phase.offset)} animation: { phase inswitch phase {case .start: .easeIn(duration: 0.3)case .loading: .easeInOut(duration: 0.5)case .finish: .easeOut(duration: 0.1)}}}
}

SwiftUI 框架引入了新的 PhaseAnimator 视图,它遍历阶段序列,允许为每个阶段提供不同的动画,并在阶段更改时更新内容。还有 KeyframeAnimator 视图,可以使用关键帧来实现动画。

ScrollView

今年 ScrollView 有了很多优秀的新增功能。首先,可以使用 scrollPosition 视图修饰符来观察内容偏移量。

struct ContentView: View {@State private var scrollPosition: Int? = 0var body: some View {ScrollView {Button("Scroll") {scrollPosition = 80}ForEach(1..<100, id: \.self) { number inText(verbatim: number.formatted())}.scrollTargetLayout()}.scrollPosition(id: $scrollPosition)}
}

如上例所示,使用 scrollPosition 视图修饰符将内容偏移量绑定到一个状态属性上。每当用户滚动视图时,它会通过设置第一个可见视图的标识来更新绑定。还可以通过编程方式滚动到任何视图,但是,应该使用 scrollTargetLayout 视图修饰符来告诉 SwiftUI 框架在哪里查找标识以更新绑定。

struct ContentView: View {var body: some View {ScrollView {ForEach(1..<100, id: \.self) { number inText(verbatim: number.formatted())}.scrollTargetLayout()}.scrollTargetBehavior(.paging)}
}

可以通过使用 scrollTargetBehavior 视图修饰符来更改滚动行为。它允许在滚动视图中启用分页。

搜索

与搜索相关的视图修饰符也有一些很好的新增功能。例如,可以通过编程方式聚焦到搜索字段。

struct ProductsView: View {@State private var store = Store()@State private var query = ""@State private var scope: Scope = .defaultvar body: some View {List(store.products, id: \.self) { product inText(verbatim: product)}.task {if store.products.isEmpty {await store.fetch()}}.searchable(text: $query, isPresented: .constant(true), prompt: "Query").searchScopes($scope, activation: .onTextEntry) {Text(verbatim: scope.rawValue)}}
}

如上例所示,可以使用可搜索视图修饰符的 isPresented 参数来显示/隐藏搜索字段。还可以使用 searchScopes 视图修饰符的 activation 参数来定义范围的可见性逻辑。

新手势

新增的 RotateGestureMagnifyGesture 使我们能够跟踪视图的旋转和放大。

struct RotateGestureView: View {@State private var angle = Angle(degrees: 0.0)var rotation: some Gesture {RotateGesture().onChanged { value inangle = value.rotation}}var body: some View {Rectangle().frame(width: 200, height: 200, alignment: .center).rotationEffect(angle).gesture(rotation)}
}

新增的小功能

增加了全新的 ContentUnavailableView 类型,当需要显示空视图时可以使用它。示例如下:

struct ProductsView: View {@State private var store = Store()var body: some View {List(store.products, id: \.self) { product inText(verbatim: product)}.background {if store.products.isEmpty {ContentUnavailableView("Products list is empty", systemImage: "list.dash")}}.task {if store.products.isEmpty {await store.fetch()}}}
}

还有新增了新的视图修饰符,允许调整列表中的间距。可以使用 listRowSpacinglistSectionSpacing 视图修饰符来设置列表中所需的间距。EnvironmentValues 结构体包含了一系列与最新平台更新相关的新属性,例如 isActivityFullscreenshowsWidgetContainerBackground。Swift Charts 也具有可滚动和可动画的功能。

#Preview {ContentView()
}

还有一个新的 Preview 宏,可以让我们轻松地为 UIKit 和 SwiftUI 构建预览,只需几行代码。

总结

SwiftUI 框架中有许多小的新增功能,我们将会继续分享。希望能帮到你。

特别感谢 Swift社区 编辑部的每一位编辑,感谢大家的辛苦付出,为 Swift社区 提供优质内容,为 Swift 语言的发展贡献自己的力量。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/3298.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【FPGA】Verilog:时序电路 | 触发器电路 | 上升沿触发 | 同步置位 | 异步置位

前言&#xff1a;本章内容主要是演示Vivado下利用Verilog语言进行电路设计、仿真、综合和下载 示例&#xff1a;触发器电路 ​ 功能特性&#xff1a; 采用 Xilinx Artix-7 XC7A35T芯片 配置方式&#xff1a;USB-JTAG/SPI Flash 高达100MHz 的内部时钟速度 存储器&#xff1a;…

VS2022 And QtCreator10 调试 Qt 源码教程

文章目录 背景IDE 调试 Qt 源码Visual Studio 2022Qt Creator 10.0.1 排查思路姊妹篇系列 简 述&#xff1a; 记录使用 Visual Studo 2022 和 QtCreator10 调试 Qt 5.15 源码和 加载 .pdb 的方法。 本文初发于 “偕臧的小站”&#xff0c;同步转载于此。 背景 源码&#xff1a;…

软考A计划-系统集成项目管理工程师-项目范围管理(一)

点击跳转专栏>Unity3D特效百例点击跳转专栏>案例项目实战源码点击跳转专栏>游戏脚本-辅助自动化点击跳转专栏>Android控件全解手册点击跳转专栏>Scratch编程案例点击跳转>软考全系列 &#x1f449;关于作者 专注于Android/Unity和各种游戏开发技巧&#xff…

C# Excel 表列序号

171 Excel 表列序号 给你一个字符串 columnTitle &#xff0c;表示 Excel 表格中的列名称。返回 该列名称对应的列序号 。 例如&#xff1a; A -> 1 B -> 2 C -> 3 … Z -> 26 AA -> 27 AB -> 28 … 示例 1: 输入: columnTitle “A” 输出: 1 示例 2: …

数据库原理之数据库事物

文章目录 一、事物介绍1.1 事物的目的是保证数据的一致性1.2 事物的ACID A、I、D是为了实现 C1.3 什么是本地事物(Local Transactions) 二、数据库系统如何实现ACID2.1 影响深远的ARIES理论2.2 本地事物如何实现原子性和持久性 A、D2.2.1 实现原子性和持久性的Commit Logging方…

基于物联网、区块链技术的质量管控防伪溯源系统源码

一物一码防伪溯源系统能准确获取产品生产经营各个环节的真实信息&#xff0c;利用物联网、云计算 、区块链、人工智能、5G等先进技术&#xff0c;结合特有的码码关联和RSA加密验证技术&#xff0c;建立区块链的“身份证”&#xff0c;针对产品生长到销售各环节的质量安全数据进…

结构体和数据结构--结构体数组的定义和初始化

目录 一、结构体数组的定义 二、结构体数组的初始化 一、结构体数组的定义 一个结构体变量只能表示学生成绩管理表中的一个学生的记录信息&#xff0c;代表其中的一个实例&#xff0c;而实际数据库中有多个学生的记录&#xff0c;每个记录对应一个学生的信息&#xff0c;如何…

MySQL----MHA高可用

文章目录 一、MHA理论1.1什么是 MHA1.2MHA 的组成1.3MHA 的特点 二、MHA的一主两从部署实验设计故障修复步骤&#xff1a; 一、MHA理论 1.1什么是 MHA MHA&#xff08;MasterHigh Availability&#xff09;是一套优秀的MySQL高可用环境下故障切换和主从复制的软件。 MHA 的出…

初识Docker:(7)查询Docker镜像的DockerFile

1. 前言 我们知道了根据dockerfile来制作镜像&#xff0c;如果给你一个现成的镜像&#xff0c;你能逆向查看出dockerfile吗&#xff1f; 否则&#xff0c;你怎么知道该镜像使用的是CMD还是ENTRYPOINT &#xff0c;使用的是shell格式还是CMD格式&#xff1f;由于格式决定了doc…

【HTML5】svg 绘制图形

文章目录 一、基本介绍二、用法详解2.1、矩形&#xff08;rect&#xff09;2.2、圆形&#xff08;circle&#xff09;2.3、椭圆&#xff08;ellipse&#xff09;2.4、线条&#xff08;line&#xff09;2.5、折线&#xff08;polyline&#xff09;2.6、多边形&#xff08;polygo…

Anaconda详细安装及配置教程(Windows)

Anaconda详细安装及配置教程&#xff08;Windows&#xff09; 一、下载方式1、官网下载2、网盘下载 二、安装三、配置四、创建虚拟环境 一、下载方式 1、官网下载 点击下载 点击window下载即可。 2、网盘下载 点击下载 二、安装 双击运行 点next 点I agree next 如…

springboot定时任务详解

文章目录 一、基于注解&#xff08;静态&#xff09;1、添加依赖2、创建定时任务3、参数说明 二、基于接口&#xff08;动态&#xff09;1、添加依赖2、添加数据库记录3、创建定时器4、启动测试 三、Quartz1、添加依赖2、编写任务类3、编写配置类4、启动项目 在我们开发项目过程…