SwiftUI中BottomRectangle添加@State后为何出现动画效果?
问题:SwiftUI中BottomRectangle意外出现持续变色动画的原因
初始代码
struct ContentView: View { var randColor: Color { Color(red: randomNumber/255, green: randomNumber/255, blue: randomNumber/255) } @State var isAnimation = false var randomNumber: Double { return Double.random(in: 0...255) } var body: some View { VStack { Rectangle() .fill(isAnimation ? randColor : .red) .frame(width: 200, height: 200) .onAppear { withAnimation(.easeIn(duration: 1).repeatForever(autoreverses: true)) { isAnimation = true } } BottomRectangle() } } } struct bottomRectangle: View { var randomNumber: Double { return Double.random(in: 0...255) } var body: some View { Rectangle() .fill(Color(red: randomNumber/255, green: randomNumber/255, blue: randomNumber/255)) .frame(width: 100, height: 100) } }
初始代码中,BottomRectangle视图没有颜色变化和动画效果。
修改后的代码
仅对BottomRectangle做了两处修改:
- 添加
@State var a = false - 将Rectangle的fill修改为
a ? Color.blue : Color(red: randomNumber/255, green: randomNumber/255, blue: randomNumber/255)
修改后的代码如下:
struct BottomRectangle: View { @State var a = false var randomNumber: Double { return Double.random(in: 0...255) } var body: some View { Rectangle() .fill(a ? Color.blue : Color(red: randomNumber/255, green: randomNumber/255, blue: randomNumber/255)) .frame(width: 100, height: 100) } }
修改后,BottomRectangle出现了持续变色的动画效果,无法理解该现象的原因,请求帮助。
原因解析
这是SwiftUI的动画环境继承与视图重计算机制共同作用的结果:
- 动画环境的传递:父视图
ContentView中通过withAnimation设置了永久重复的动画,这个动画环境会自动传递给所有子视图。初始状态的BottomRectangle没有依赖任何@State类的可变属性,SwiftUI判定它是静态视图,只会计算一次颜色值,因此不会产生动画。 - @State触发动态重绘:给
BottomRectangle添加@State var a = false后,该视图被标记为“可动态更新”的视图。即便你没有主动修改a的值,在父视图的持续动画环境下,SwiftUI会周期性地重新计算这个子视图的body属性。 - 随机值的动态刷新:每次
body重计算时,randomNumber都会生成新的随机值,导致填充颜色变化。而父视图传递的重复动画环境会让SwiftUI自动将颜色变化插值为平滑过渡,最终呈现出持续变色的动画效果。
简单概括:父视图的循环动画让子视图进入持续重绘周期,新增的@State让SwiftUI认为该视图可动态更新,每次重绘时随机色刷新,再加上继承的动画环境,就产生了持续变色的效果。
内容的提问来源于stack exchange,提问作者iyeaaa
相关产品推荐
相关产品推荐

