animation动画不生效_SwiftUI动画(1)之Animatable

2f1e18350f50ab55b986ff460e4876ca.png

相信大家都已经对SwiftUI有了基本的了解,在SwiftUI写动画,相对来说变得更加简单了,接下来,会用3篇文章,带领大家一览SwiftUI动画的魅力。

1. 显式和隐式动画

在SwiftUI中有两种类型的动画,显式和隐式。

隐式动画指的就是用animation()modifier的view,当该view的可动画的参数变化的时候,系统会自动进行动画,这些所谓的可动画的参数包括size,offsetcolorscale等等。

显式动画指的是withAnimation { ... }闭包中指定的参数,所有依赖这些参数的view,都会执行动画。

我们先看个例子,下边的动画使用了隐式动画:

edfc1a82f3aefb20954416585b26df07.gif

代码如下:

struct Example1: View {
    
    @State private var half = false
    @State private var dim = false

    var body: some View {
    
        Image("tower")
            .scaleEffect(half ? 0.5 : 1.0)
            .opacity(dim ? 0.2 : 1.0)
            .animation(.easeInOut(duration: 1.0))
            .onTapGesture {
    
                self.dim.toggle()
                self.half.toggle()
            }
    }
}

从上边的代码中,我们可以看出动画依赖half,dim这2个参数,我们并没有直接告诉view这2个参数要动画,系统会自动把旧值到新值的变化做动画。

我们把代码做一点简单的改变:

struct Example2: View {
    
    @State private var half = false
    @State private var dim = false

    var body: some View {
    
        Image("tower")
            .scaleEffect(half ? 0.5 : 1.0)
            .opacity(dim ? 0.5 : 1.0)
            .onTapGesture {
    
                self.half.toggle()

                withAnimation(.easeInOut(duration: 1.0)) {
    
                    self.dim.toggle()
                }
        }
    }
}

我们去掉了.animation(.easeInOut(duration: 1.0)),新增了withAnimation闭包,我们把self.dim.toggle()放到闭包中,这就是显式的告诉系统,view的透明度要执行xxx动画,所有依赖dim参数的view,在dim改变的时候,都会执行动画,效果如下:

f954984ffcca2c96c4a63aa8061297bd.gif

仔细看上图的动画过程,就会发现,只有透明度指定了动画,缩放并没有执行动画,这就说明,我们显式的告诉系统dim需要动画,它就只为dim执行动画,非常的听话。

此时此刻,我有一个问题,我用隐式动画如何实现上边这种动画呢?也非常简单,先看代码:

struct Example2: View {
    
    @State private var half = false
    @State private var dim = false

    var body: some View {
    
        Image("tower")
            .opacity(dim ? 0.2 : 1.0)
            .animation(.easeInOut(duration: 1.0))
            .scaleEffect(half ? 0.5 : 1.0)
            .onTapGesture {
    
                self.dim.toggle()
                self.half.toggle()
        }
    }
}

animationmodifier作用于view时,他的顺序时很重要的,在上边的代码中,它只对它前边的内容生效,当然这个顺序我们其实时可以任意调整的,我们要想使用隐式动画禁用某些动画时,只需要.animation(nil)就行了。

struct Example2: View {
    
    @State private var half = false
    @State private var dim = false

    var body: some View {
    
        Image("tower")
            .opacity(dim ? 0.2 : 1.0)
            .animation(nil)
            .scaleEffect(half ? 0.5 : 1.0)
                .animation(.easeInOut(duration: 1.0))
            .onTapGesture {
    
                self.dim.toggle()
                self.half.toggle()
        }
    }
}

2.How Do Animations Work

SwiftUI动画背后的原理在于Animatable协议,它要求我们实现一个计算属性animatableData,该属性遵守VectorArithmetic协议,VectorArithmetic的目的是让系统可以在需要变化的动画数据中间插入很多值,这些值的计算依赖动画的时间函数。

本质上,在SwiftUI中执行动画,就是系统渲染View很多次,每一次渲染,都改变一点点参数,当然,这个参数指的是需要动画的原值到终值。

举个例子,如果我们线性的把透明度从0.3改成0.8,由于0.3是Double类型,实现了VectorArithmetic协议,因此系统可以在0.3到0.8之间插入很对中间的值,这些值的计算依赖时间函数和动画时长。在本例中,它是线性的,系统在插

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值