在 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开发者提供了更强大的动画工具。

相关内容

热门资讯

免费测试版!(来趣广西麻将)外... 免费测试版!(来趣广西麻将)外挂透明挂辅助器(透视挂)规律教程(2024已更新)(哔哩哔哩);是一款...
分辨真假!微信小程序打牌可以开... 分辨真假!微信小程序打牌可以开挂,菜鸟黑桃a3原来是有挂猫腻,爆料教程(有挂规律)-哔哩哔哩;微信小...
5分钟了解!微扑克辅助器是骗人... 5分钟了解!微扑克辅助器是骗人外挂透明挂透视,WPK最新版软件透明挂,详细教程(有挂技巧)-哔哩哔哩...
发现一款((Wepoke透视)... 发现一款((Wepoke透视))微扑克ai辅助(辅助挂)外挂透明挂辅助安装(2024已更新)(哔哩哔...
四分钟了解!wepoker辅助... 《wepoker软件透明挂》是一款多人竞技的wepoker辅助透视游戏,你将微扑克对手来到同一个战场...
玩家实测!hhpoker是真的... 玩家实测!hhpoker是真的吗,wepoker开辅助能查到吗,wepoker透视器免费(2024已...
科普常识!(雀友会辅助器苹果版... 您好,雀友会辅助器苹果版这款游戏可以开挂的,确实是有挂的,需要了解加微【757446909】很多玩家...
程序员教你!白金岛跑得快辅助器... 程序员教你!白金岛跑得快辅助器,河洛杠原来是有挂猫腻,技巧教程(果真有挂)-哔哩哔哩;1、点击下载安...
九分钟透视辅助!aapoker... 您好,Wepoke黑科技这款游戏可以开挂的,确实是有挂的,需要了解加微【136704302】很多玩家...
推荐十款!(乐胡麻将)外挂透明... 推荐十款!(乐胡麻将)外挂透明挂辅助助手(透视挂)AI教程(2025已更新)(哔哩哔哩)是一款可以让...