每次视图出现时,SwiftUI .onAppear withAnimation 都会加快速度。为啥?
Posted
技术标签:
【中文标题】每次视图出现时,SwiftUI .onAppear withAnimation 都会加快速度。为啥?【英文标题】:SwiftUI .onAppear withAnimation speeds up each time the view appears. Why?每次视图出现时,SwiftUI .onAppear withAnimation 都会加快速度。为什么? 【发布时间】:2021-08-03 04:10:29 【问题描述】:我的应用中有在onAppear
上触发并使用withAnimation
配置的持续动画,更新@State
属性。
每次视图出现时,动画都会比以前快一点,所以如果视图被显示,然后被模态显示覆盖或隐藏在导航中,然后再次出现,动画开始运行得非常非常快——也许比应有的速度快 10 或 20 倍。
这是代码...
struct HueRotationAnimation: ViewModifier
@State var hueRotationValue: Double
func body(content: Content) -> some View
content
.hueRotation(Angle(degrees: hueRotationValue))
.onAppear()
DispatchQueue.main.async
withAnimation(.linear(duration: 20).repeatForever(autoreverses: false))
hueRotationValue += 360
struct GradientCircle: View
var gradient: Gradient
@State var hueRotationValue: Double = Double.random(in: 0..<360)
var body: some View
GeometryReader geometry in
Circle()
.fill(
radialGradient(geometry: geometry, gradient: gradient)
)
.modifier(HueRotationAnimation(hueRotationValue: hueRotationValue))
func radialGradient(geometry: GeometryProxy, gradient: Gradient) -> RadialGradient
RadialGradient(gradient: gradient,
center: .init(x: 0.82, y: 0.85),
startRadius: 0.0,
endRadius: max(geometry.size.width, geometry.size.height) * 0.8)
知道每次视图重新出现时导致速度加快的原因吗?有什么解决这个问题的建议吗?
(注意:这是运行 Xcode 13.0 beta 4)
【问题讨论】:
【参考方案1】:我认为这与您的 += 360 有关,因为每次它出现时,它需要旋转的度数再增加 360 度。不要在出现时添加 360,而是尝试为动画应该运行的时间设置一个状态布尔值。试试下面的代码,看看它是否适合你。
struct HueRotationAnimation: ViewModifier
@State var hueRotationValue: Double
@State private var animated = false
func body(content: Content) -> some View
content
.hueRotation(Angle(degrees: animated ? hueRotationValue : hueRotationValue + 360)).animation(.linear(duration: 20).repeatForever(autoreverses: false))
.onAppear()
self.animated.toggle()
这样 360 度动画应该保持 360 度并且动画的速度不应该改变。
【讨论】:
出色的解释和优雅的解决方案。谢谢。【参考方案2】:为了推进,@yawnobleix 的回答,我添加了一个 .onDisappear 切换。它解决了视图出现>消失>出现时的一些其他错误。
struct HueRotationAnimation: ViewModifier
@State var hueRotationValue: Double
@State private var animated = false
func body(content: Content) -> some View
content
.hueRotation(Angle(degrees: animated ? hueRotationValue : hueRotationValue + 360)).animation(.linear(duration: 20).repeatForever(autoreverses: false))
.onAppear
animated = true
.onDisappear
animated = false
【讨论】:
以上是关于每次视图出现时,SwiftUI .onAppear withAnimation 都会加快速度。为啥?的主要内容,如果未能解决你的问题,请参考以下文章
在 SwiftUI 中使用 onAppear 时出现无限循环