动画(三) – 动画协议

温馨提示:本文最后更新于2024-10-23 18:36:44,某些文章具有时效性,若有错误或已失效,请在下方留言

SwiftUI 属性动画系统的核⼼是 Animatable 协议。这个协议可以被视图和视图修饰符所实现,它们通过该协议把可以进⾏动画的属性暴露给SwiftUI。

这个协议唯⼀的要求是⼀个 animatableData 属性,它的默认实现什么都没有做。

struct Shake: ViewModifier, Animatable {
    var numberOfShakes: Double
    
    var animatableData: Double {
        get { numberOfShakes }
        set { numberOfShakes = newValue }
    }
    
    func body(content: Content) -> some View {
        content
            .offset(x: -sin(numberOfShakes * 2 * .pi) * 30)
    }
}

struct ContentView: View {
    @State private var shakes = 0
    
    var body: some View {
        Button("Shake!") {
            shakes += 1
        }
        .modifier(Shake(numberOfShakes: Double(shakes)))
        .animation(.default, value: shakes)
    }
}

效果演示
效果演示

当⽤户点击这个抖动按钮时,shakes 状态数据被加⼀。新的视图树的结构和渲染树是相同的,只有属性发⽣了改变。在渲染树中,Shake 的 numberOfShakes 值为 0,⽽在新的视图树中,它的值是 1。

动画效果
动画效果

因为 Shake 上的 animatableData 属性只是简单地转发和承接了 numberOfShakes 属性,所以 Shake 上的 animatableData 也从 0 变成了 1。SwiftUI 将会把这个变更通过 .default 时间曲线从 0 到 1 进⾏插值。每次 animatableData 改变时,视图修饰器的 body 都会被重新执⾏,于是视图在屏幕上的按钮将被更新。


参考 《Thinking In SwiftUI》

© 版权声明
THE END
喜欢就支持一下吧
点赞11 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容