在 SwiftUI 中,withAnimation 是一个简单而强大的方式,用来在状态或视图的更改时,平滑地应用动画效果。
withAnimation {
// 状态或视图的变更代码
}
当withAnimation内的代码发生变更时,视图会以平滑的方式进行变更。
示例代码
1、基本用法
withAnimation 会在改变状态的同时自动应用动画。
import SwiftUI
struct ContentView: View {
@State private var isExpanded = false
var body: some View {
VStack {
Button("Toggle") {
withAnimation {
isExpanded.toggle()
}
}
.padding()
if isExpanded {
Rectangle()
.fill(Color.blue)
.frame(width: 200, height: 200)
.transition(.scale)
}
}
}
}
解释:
按下按钮后,isExpanded 状态改变,Rectangle 的显示使用了默认的动画。
withAnimation 可以结合 transition 为视图增添进出动画。
2、使用自定义动画
withAnimation 允许指定动画类型。
withAnimation(.easeInOut(duration: 0.5)) {
// 状态变化
}
示例:
import SwiftUI
struct ContentView: View {
@State private var offset: CGFloat = 0
var body: some View {
VStack {
Button("Move") {
withAnimation(.spring(response: 0.5, dampingFraction: 0.6, blendDuration: 0)) {
offset += 50
}
}
Circle()
.fill(Color.red)
.frame(width: 50, height: 50)
.offset(x: offset, y: 0)
}
}
}
解释:
withAnimation 内指定了 spring 弹簧动画,具有自然的回弹效果。
隐式动画与显式动画的区别
隐式动画:直接在修饰符中绑定动画,如 .animation()
Circle()
.animation(.easeInOut(duration: 0.5), value: scale) // 绑定动画到状态
显式动画:使用 withAnimation {} 明确定义动画。
选择哪种方式取决于需求:
隐式动画适合简单绑定,代码简洁。
显式动画更灵活,可以嵌套、指定多个动画。
动画的进阶技巧
1、动画叠加:多个动画同时作用
withAnimation(.easeIn(duration: 0.5)) {
// 动画 1
}
withAnimation(.spring()) {
// 动画 2
}
2、动画的条件组合
通过状态切换和 transition 设置动画效果。
Rectangle()
.transition(.opacity.combined(with: .slide))
3、控制动画开始/暂停
通过 .transaction 或 .animation(nil) 停止动画。
总结
withAnimation 是实现 SwiftUI 动画的核心之一。
对于更复杂的需求,可以结合 .animation、transition 和 TimelineView 实现更多效果。
尝试不同的动画类型(如 spring、easeInOut)以调整效果。