SwiftUI 中淡入淡出特效
>
>
import SwiftUI struct Bounce: AnimatableModifier { let animCount: Int var animValue: CGFloat var amplitude: CGFloat // 振幅 var bouncingTimes: Int init(animCount: Int, amplitude: CGFloat = 10, bouncingTimes: Int = 3) { self.animCount = animCount self.animValue = CGFloat(animCount) self.amplitude = amplitude self.bouncingTimes = bouncingTimes } var animatableData: CGFloat { get { animValue } set { animValue = newValue } } func body(content: Content) -> some View { let t = animValue - CGFloat(animCount) let offset: CGFloat = -abs(pow(CGFloat(M_E), -t) * sin(t * .pi * CGFloat(bouncingTimes)) * amplitude) return content.offset(y: offset) } } struct InOut: Animatable { } extension View { func bounce(animCount: Int, amplitude: CGFloat = 10, bouncingTimes: Int = 3) -> some View { self.modifier(Bounce(animCount: animCount, amplitude: amplitude, bouncingTimes: bouncingTimes)) } } struct ContentView: View { @State var taps = 0 var body: some View { VStack{ Button(action: { withAnimation(Animation.linear(duration: 1)) { taps += 1 } }, label: { RoundedRectangle(cornerRadius: 15) .bounce(animCount: taps) }) .frame(width: 100, height: 100) Button(action: { taps += 1}, label: { Image(systemName: "person") .resizable() }) .frame(width: 100, height: 100) .background(Color.red) } } }
Bounce
是一个自定义的动画修饰器(Modifier),用于实现按钮的弹跳效果。它采用AnimatableModifier
协议,其中包括了动画计数、振幅和弹跳次数等参数。animatableData
属性允许 SwiftUI 动画系统追踪animValue
的变化。在body(content:)
方法中,使用数学公式计算按钮在垂直方向上的偏移,以实现弹跳效果。