IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> SwiftUI——iOS15新版Animation制作动画介绍 -> 正文阅读

[移动开发]SwiftUI——iOS15新版Animation制作动画介绍

从iOS 15.0开始,苹果废弃了之前的.animation(Animation?),建议开发者使用.animation(Animation?, value: Equatable)或者withAnimation替代。

个人感觉改版之后虽然可能有些不习惯,但是开发的可能性和自由度更大了。

但是在讲二者区别之前,我们需要了解一下UI动画。如果你了解这部分可以跳过。

何为动画

动画是由各种位移、颜色变化、大小变化等属性变化的过程。
具体到SwiftUI的View,就是它们的.offset.foregroundColor.frame等属性逐渐变化的时候产生的效果。
但是如果你直接改变变量,属性会直接变化,非常生硬,这不能被称为动画。苹果提供了非常简单的实现过度动画的办法,那就是.animation

可以理解成我们设定好关键帧,然后设置中间帧就可以做出动画啦!

不同样式的过度动画(中间帧)

苹果提供了很简单的方式,但是或许是太简单了,就没有人详细说说这个。

首先动画运动节奏也分很多种,例如缓进缓出、匀速运动等,所以这里介绍一下苹果提供的几种模式(如果是nil就是无动画):
请添加图片描述
具体的代码后面会列出来,因为有一个特性这里还没提,所以这里先不列出代码。

新旧版本不同之处

现在我们具体说明一下.animation(Animation?,).animation(Animation?, value: Equatable)二者之间的不同之处。
老版的.animation(Animation?)是放在需要运动或者改变的View下面,当View改变的时候,出现过渡动画,过渡动画包括运动、样式、颜色等属性。
新版.animation(Animation?, value: Equatable)比老版多了一个参数,那就是value
这个参数value的作用是当这个值发生改变的时候,才会出现应用我们指定的过度动画,过渡动画也包括运动、样式、颜色等属性。如果View的其他属性发生变化,则不会出现动画。
所以上面那个动画的代码如下:

struct AnimationView: View {
    @State private var offsetX: CGFloat = 150
    var body: some View {
        VStack {
            VStack {
                Text(".default(默认)")
                Rectangle()
                    .frame(width: 30, height: 30)
                    .offset(x: offsetX)
                    .foregroundColor(Color.pink)
                    /* 如果是`nil`就是无动画 */
                    .animation(.default, value: offsetX)
                
                Text(".linear(匀速)")
                Rectangle()
                    .frame(width: 30, height: 30)
                    .offset(x: offsetX)
                    .foregroundColor(Color.pink)
                    .animation(.linear, value: offsetX)
                
                Text(".easeIn(开头缓慢,逐渐加速)")
                Rectangle()
                    .frame(width: 30, height: 30)
                    .offset(x: offsetX)
                    .foregroundColor(Color.pink)
                    .animation(.easeIn, value: offsetX)
                
                Text(".easeOut(结尾逐渐减速,缓慢结束)")
                Rectangle()
                    .frame(width: 30, height: 30)
                    .offset(x: offsetX)
                    .foregroundColor(Color.pink)
                    .animation(.easeOut, value: offsetX)
                
                Text(".easeInOut(缓出缓进,上面的融合体)")
                Rectangle()
                    .frame(width: 30, height: 30)
                    .offset(x: offsetX)
                    .foregroundColor(Color.pink)
                    .animation(.easeInOut, value: offsetX)
            }
            
            Button(action: {
                offsetX = -150
            }, label: {
                Text("开始运动")
                    .padding()
                    .overlay(
                        RoundedRectangle(cornerRadius: 15)
                            .stroke(lineWidth: 3)
                    )
            })
        }
    }
}

但是由于这个value,我们只能当这个值发生变化的时候才能有动画,那么如果我们需要在观察到几个值当中的某一个发生变化就有动画的话,那该怎么办呢?

如果你要观察的值是同一个类型的话,那么可以使用数组,例如[offsetX, offsetY],这样的话就相当于观察这个数组有没有变化了,只要有一个值发生变化,那么数组就会变化。这样可以达到我们需要的效果。

需要观察多个值该怎么办

如果需要观察的值不是同一个类型的,例如我们要观察位移和颜色,一个是CGFloat类型,一个是Color类型。这样就很麻烦了。所以这里列举有几个解决方案,以防在某种情况下,某种方法会更加麻烦:

第一种:
可以搞个数据结构,然后观察数据。或许某种情况你用这种方法很方便,
首先新建一个结构体,协议是Equatable,如下:

struct Test: Equatable {
    var offsetX: CGFloat
    var color: Color
}

然后是View部分:

.animation(.default, value: Test(offsetX: offsetX, color: color))

这种方法相对来说通用一些,而且可以观察多次变化,就是有点麻烦。

第二种:
由于value是符合Equatable协议的,也就是说这里的value其实是个Bool值,我们虽然写作value: color这种,但是实际上它是在判断这个值有没有发生变化,相当于color == 之前的color,通过这个来返回一个Bool值(很经典的C语言编程技巧,如果你熟悉C语言应该很容易就明白了)。
但是我们不能直接放个Bool值在这,就想它必须出动画或者不出动画,那是不会的。它是必须要判断这个值有没有发生变化的。
所以我们可以写成这样:

.animation(.default, value: offsetX == 150 && color == Color.pink)

这种方法的写法相对简单,但是由于只对比一个值,所以某些情况下可能不好用。

动画时间长度

我们可以设置过渡动画的时长,来控制动画的快慢和节奏,这个很简单。老版本的可能很多人都会用,但是新版本由于官方没提,网上也没人说,所以这里讲一下。

在动画样式的后面加个(duration: 时长)即可,时长的单位是

//这里表示动画时长为3秒
.animation(.linear(duration: 3), value: offsetX)

总结

看到这里你应该就可以做出简单的动画啦,不过我还会写一些相关的概念、技巧的博客,来帮助需要的人。

希望能帮到有需要的人~

  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2022-02-19 01:17:18  更:2022-02-19 01:17:29 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 14:35:59-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码