LazyVStack 滚动停止动画 [英] LazyVStack scrolling stops animations
问题描述
此代码列出了 100 行,带有刷新图标动画.当使用 LazyVStack
而不是 VStack
时,向下滚动到此列表底部后,所有动画都会停止,包括列表顶部的动画,一旦您向后滚动.VStack
没有这样的问题.关于为什么会发生这种情况的任何想法,是否有解决方法?使用 Xcode 12.0.1、iOS 14、Swift 5
This code lists 100 rows with refresh icon animations. When using a LazyVStack
instead of a VStack
, after scrolling down to the bottom of this list all the animations stop, including those at the top of the list once you scroll back. No such issues with a VStack
. Any ideas as to why this is happening and is there a workaround?
Using Xcode 12.0.1, iOS 14, Swift 5
struct RefreshingList : View {
@State var isAnimating = false
var body: some View {
ScrollView {
LazyVStack { // <- change to VStack to have animations not stop
ForEach(0..<100, id: \.self) { i in
HStack {
Text("\(i) -> ")
self.button()
}
}
}
}
.onAppear {
self.isAnimating=true
}
}
func button() -> some View {
Button(action: {}, label: {
Image(systemName: "arrow.2.circlepath")
.rotationEffect(Angle(degrees: self.isAnimating ? 360.0 : 0.0))
.animation(Animation.linear(duration: 2.0)
.repeatForever(autoreverses: false))
})
}
}
推荐答案
当观察到屏幕上的视图发生变化时会发生动画.在 VStack
中,所有视图都会立即创建,因此 SwiftUI 能够观察所有视图的旋转值变化.
Animation happens when a change to a view on screen is observed. In the VStack
all of the views are created immediately so SwiftUI is able to observe the change in rotation value for all views.
在 LazyVStack
的情况下,视图只在需要时创建,所以当 .onAppear
中的旋转值改变时,底部的视图不会出现在屏幕上.当它们确实出现在屏幕上时,它具有已更改的值,因此不会发生动画.
In the LazyVStack
case, the views are only created as needed, so the bottom ones aren't on screen when the rotation value changes in .onAppear
. When they do appear on screen, it is with the already changed value, so no animation happens.
解决此问题的一种方法是让按钮拥有 .isAnimating
@State
变量.然后任何时候创建一个,它就会被动画化.
One way to fix this is to let the buttons own the .isAnimating
@State
variable. Then anytime one is created, it will be animating.
struct RefreshingList : View {
var body: some View {
ScrollView {
LazyVStack {
ForEach(0..<100, id: \.self) { i in
HStack {
Text("\(i) -> ")
AnimatedButton()
}
}
}
}
}
}
struct AnimatedButton: View {
@State var isAnimating = false
var body: some View {
Button(action: {
}, label: {
Image(systemName: "arrow.2.circlepath")
.rotationEffect(Angle(degrees: self.isAnimating ? 360.0 : 0.0))
.animation(Animation.linear(duration: 2.0)
.repeatForever(autoreverses: false))
})
.onAppear {
isAnimating = true
}
}
}
这篇关于LazyVStack 滚动停止动画的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!