在 SwiftUI 中的作用域动画
创始人
2024-09-25 11:50:54
0

在这里插入图片描述

在这里插入图片描述

文章目录

    • 前言
    • 简单示例
    • 动画视图修饰符
    • 使用多个可动画属性
    • 使用 ViewBuilder
    • 总结

前言

从一开始,动画就是 SwiftUI 最强大的功能之一。你可以在 SwiftUI 中快速构建流畅的动画。唯一的缺点是每当我们需要运行多步动画或将动画范围限定到视图层次结构的特定部分时,我们如何控制动画。

简单示例

让我们从一个简单的示例开始,展示我们旧方法的一些缺点,这些方法用于在 SwiftUI 中驱动动画。

struct ContentView: View {     @State private var isHidden = false          var body: some View {         VStack {             Button("Animate") {                 isHidden.toggle()             }                          HugeView()                 .opacity(isHidden ? 0.0 : 1.0)                              AnotherHugeView()         }         .animation(.default)     } } 

如上例所示,我们有一个包含按钮和两个视图的视图层次结构,这些视图放置在垂直堆栈中。我们将动画视图修饰符附加到整个堆栈,以动画堆栈内的任何更改。

当我们按下按钮时,堆栈会动画显示内部的任何更改。但是,动画视图修饰符不连接到 isHidden 属性,这意味着它将动画显示可能发生的任何更改。其中一些更改可能是意外的,比如环境值的变化。

动画视图修饰符

我们可以通过使用动画视图修饰符的另一个版本来消除意外动画,在这个版本中,我们可以绑定到特定值,并且仅在值更改时进行动画处理。

struct ContentView: View {     @State private var isHidden = false          var body: some View {         VStack {             Button("Animate") {                 isHidden.toggle()             }                          HugeView()                 .opacity(isHidden ? 0.0 : 1.0)                          AnotherHugeView()         }         .animation(.default, value: isHidden)     } } 

在上面的示例中,我们使用了带有 value 参数的动画视图修饰符。它允许我们将动画范围限定为单个值,并仅在与特定值相关的更改时执行动画。在这种情况下,我们没有任何意外的动画。

使用多个可动画属性

如果我们有多个可动画属性怎么办?

在这种情况下,我们必须为每个可动画属性附加一个动画修饰符。这个解决方案非常有效,但在人体工程学方面有一个缺点。

struct ContentView: View {     @State private var firstStep = false     @State private var secondStep = false          var body: some View {         VStack {             Button("Animate") {                 Task {                     firstStep.toggle()                     try? await Task.sleep(nanoseconds: 3_000_000_000)                     secondStep.toggle()                 }             }                          // 其他视图在这里                          SomeView()                 .opacity(firstStep ? 1.0 : 0.0)                 .blur(radius: secondStep ? 0 : 20.0)         }         .animation(.default, value: firstStep)         .animation(.default, value: secondStep)     } } 

幸运的是,SwiftUI 引入了动画视图修饰符的一个新变体,允许我们使用 ViewBuilder 闭包来限定动画的范围。

struct ContentView: View {     @State private var firstStep = false     @State private var secondStep = false          var body: some View {         VStack {             Button("Animate") {                 Task {                     firstStep.toggle()                     try? await Task.sleep(nanoseconds: 1_000_000_000)                     secondStep.toggle()                 }             }                          // 其他视图在这里                          SomeView()                 .animation(.default) { content in                     content                         .opacity(firstStep ? 1.0 : 0.0)                         .blur(radius: secondStep ? 0 : 20.0)                 }         }     } } 

如上例所示,我们使用动画视图修饰符,提供我们需要的动画类型和一个 ViewBuilder 闭包,在这个动画中应用。动画仅在提供的 ViewBuilder 闭包的上下文中工作,不会扩展到其他任何地方。

使用 ViewBuilder

作为起点,ViewBuilder 闭包提供一个参数,用于占位视图,在其中应用了动画视图修饰符。在 ViewBuilder 闭包内部,可以安全地对视图应用任何视图修饰符,并期望仅对此代码块进行动画处理。

struct ContentView: View {     @State private var firstStep = false     @State private var secondStep = false          var body: some View {         VStack {             Button("Animate") {                 Task {                     firstStep.toggle()                     try? await Task.sleep(nanoseconds: 1_000_000_000)                     secondStep.toggle()                 }             }                          // 其他视图在这里                          SomeView()                 .transaction { t in                     t.animation = t.animation?.speed(2)                 } body: { content in                     content                         .opacity(firstStep ? 1.0 : 0.0)                         .blur(radius: secondStep ? 0 : 20.0)                 }         }     } } 

正如你所看到的,SwiftUI 提供了一种类似的方法,以在视图层次结构中维护有作用域的事务。

总结

这篇文章介绍了在SwiftUI中构建动画的新方法,重点解决了在多步动画或特定视图层次结构中控制动画的挑战。通过引入带有value参数的动画修饰符,以及使用ViewBuilder闭包限定动画范围,作者展示了更精确和灵活的动画控制方式。

这种方法在处理多个可动画属性时尤其强大。文章还提到了SwiftUI引入的一项新变体,使用ViewBuilder闭包可在动画中应用视图修饰符,有效地将动画范围限定在特定的上下文中。

最后,介绍了在 SwiftUI 中构建有作用域的事务的新方法,以维护更具精确性和可控性的动画。这些新功能在最新的平台上可用,为SwiftUI开发者提供了更强大的动画工具。

相关内容

热门资讯

针对!微信新众游辅助(辅助)果... 针对!微信新众游辅助(辅助)果然是真的有辅助教程(有挂细节)1、游戏颠覆性的策略玩法,独创攻略技巧玩...
黑科技辅助挂!微信牵手跑的快辅... 黑科技辅助挂!微信牵手跑的快辅助(辅助)竟然真的是有辅助器(今日头条)小薇(辅助器软件下载)致您一封...
据公告内容!乐酷大厅怎么安装(... 据公告内容!乐酷大厅怎么安装(辅助)一直是有辅助软件(真是有挂)1、完成乐酷大厅怎么安装有辅助插件,...
今年以来!新超圣辅助靠谱不(辅... 今年以来!新超圣辅助靠谱不(辅助)好像是真的有辅助教程(有挂神器)1、全新机制【新超圣辅助靠谱不ai...
据权威媒体报道!老友赣州麻将破... 据权威媒体报道!老友赣州麻将破解版(辅助)果然是有辅助神器(有挂猫腻)1、玩家可以在老友赣州麻将破解...
此事引发网友热议!闲聚鱼虾蟹软... 此事引发网友热议!闲聚鱼虾蟹软件脚本(辅助)真是真的是有辅助挂(有挂技术)1、用户打开应用后不用登录...
事发当天!边锋干瞪眼辅助器(辅... 事发当天!边锋干瞪眼辅助器(辅助)真是存在有辅助方法(有挂实锤)1、边锋干瞪眼辅助器免费辅助多个强度...
为了进一步!欢乐联盟免费辅助(... 为了进一步!欢乐联盟免费辅助(辅助)一直是有辅助软件(有挂助手)运欢乐联盟免费辅助辅助工具,进入游戏...
复盘辅助挂!和和营口辅助(辅助... 复盘辅助挂!和和营口辅助(辅助)果然是真的有辅助器(今日头条)和和营口辅助是不是有人用挂微扑克wpk...
技巧辅助挂!极速摇一摇鱼虾蟹辅... 技巧辅助挂!极速摇一摇鱼虾蟹辅助(辅助)一贯确实有辅助软件(有挂神器)极速摇一摇鱼虾蟹辅助透视方法中...