Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/docker/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Swiftui LazyVStack滚动可停止动画_Swiftui_Vstack_Lazyvstack - Fatal编程技术网

Swiftui LazyVStack滚动可停止动画

Swiftui LazyVStack滚动可停止动画,swiftui,vstack,lazyvstack,Swiftui,Vstack,Lazyvstack,此代码列出了100行刷新图标动画。当使用LazyVStack而不是VStack时,向下滚动到此列表底部后,所有动画停止,包括向后滚动时列表顶部的动画。对于VStack,没有此类问题。关于为什么会发生这种情况,有没有解决办法? 使用Xcode 12.0.1、iOS 14和Swift 5 struct RefreshingList : View { @State var isAnimating = false var body: some View { Scroll

此代码列出了100行刷新图标动画。当使用
LazyVStack
而不是
VStack
时,向下滚动到此列表底部后,所有动画停止,包括向后滚动时列表顶部的动画。对于
VStack
,没有此类问题。关于为什么会发生这种情况,有没有解决办法? 使用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))
        })
    }
}
结构刷新列表:视图{
@状态变量isAnimating=false
var body:一些观点{
滚动视图{
懒散的{//一些观点{
按钮(操作:{},标签:{
图像(系统名称:“arrow.2.circlepath”)
.旋转效应(角度(度:自旋转?360.0:0.0))
.动画(动画.线性(持续时间:2.0)
.repeatForever(自动反转:false))
})
}
}
结构刷新列表视图:视图{
var body:一些观点{
滚动视图{
懒散的{

ForEach(0..动画在观察到屏幕上视图的更改时发生。在
VStack
中,所有视图都会立即创建,以便SwiftUI能够观察到所有视图的旋转值的更改

LazyVStack
案例中,视图仅根据需要创建,因此当旋转值在
.onAppear
中更改时,底部视图不在屏幕上。当它们出现在屏幕上时,它与已更改的值一起,因此不会发生动画

解决此问题的一种方法是让按钮拥有
.isAnimating
@State
变量。然后,无论何时创建一个变量,它都将设置动画

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
        }
    }
}
结构刷新列表:视图{
var body:一些观点{
滚动视图{
懒散的{

ForEach(0..这种方式可以工作,但现在有一个不同的副作用。当我向下滚动到底部时,动画可以继续正常运行。但是当我向上滚动到顶部时,动画以相反的旋转方向运行(CCW vs CW)。如果我再次向下滚动,动画将再次反转。动画不会停止,而是反转方向。
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
        }
    }
}