动画描述
最近在思考游戏结束后,实现动画抖动的效果,实现效果如下:

SwiftUI 的抖动动画(Shake Animation)可以通过 offset 结合 withAnimation 来实现,使视图在水平方向或垂直方向上快速摆动几次。以下是几种不同的实现方式:
实现方式
1、简单版
适用于一次性抖动,例如游戏结束时的方块抖动。
import SwiftUI
struct ShakeView: View {
@State private var shakeOffset: CGFloat = 0
var body: some View {
VStack {
Text("抖动的方块")
.padding()
.background(Color.blue)
.cornerRadius(10)
.offset(x: shakeOffset)
.onTapGesture {
triggerShake()
}
}
}
private func triggerShake() {
withAnimation(Animation.linear(duration: 0.1).repeatCount(5, autoreverses: true)) {
shakeOffset = 10
}
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
shakeOffset = 0
}
}
}
struct ShakeView_Previews: PreviewProvider {
static var previews: some View {
ShakeView()
}
}
在点击动画时,调用triggerShake方法,这个方法的作用是,使用withAnimation设置一个重复动画并且shakeOffset设置x轴为10,制造抖动效果。
点击动画,发生抖动。0.5秒后,shakeOffset偏移设置为0,用于下次抖动。

2、结合 @State 触发
适用于当某个状态变更时触发抖动,比如输入错误时的文本框。
struct ShakingTextField: View {
@State private var text = ""
@State private var isShaking = false
var body: some View {
TextField("输入内容", text: $text)
.textFieldStyle(RoundedBorderTextFieldStyle())
.frame(width: 200)
.offset(x: isShaking ? -10 : 0)
.animation(isShaking ? Animation.linear(duration: 0.1).repeatCount(5, autoreverses: true) : .default, value: isShaking)
.onChange(of: text) { newValue in
if newValue.count > 5 { // 假设输入超过5个字符就触发抖动
isShaking = true
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
isShaking = false
}
}
}
}
}
用户输入错误时,输入框自动抖动提示错误。
代码主要是通过onChange监听,如果文本框长度大于5,isShaking设置为true,0.5秒延迟后设置为false。
当isShaking设置为true后,offset的x轴会偏移-10,animation通过repeatCount重复动画效果。

总结
通过offset和Animation动画的效果,最终实现动画的抖动。
相关文章
Swiftui动画animation:https://fangjunyu.com/2024/12/16/swiftui%e5%8a%a8%e7%94%bbanimation/