从.onAppear内部修改状态会导致错误“在视图更新期间修改状态,这将导致未定义的行为”

时间:2020-09-24 04:23:46

标签: swift swiftui

在真实设备上进行测试时,出现以下代码的Modifying state during view update, this will cause undefined behavior问题。在iPhone 11上进行了测试。在模拟器上,问题没有出现,并且代码按预期工作。

what I can gather中,可以从.onAppear 内部修改状态

这是怎么回事?为什么会出现此错误?

struct Clouds: View {
    @State private var cloudOffset: CGFloat = 0.0
    @State private var cloudOffset2: CGFloat = 0.0

    @EnvironmentObject var mainData: MainData
    
    var body: some View {
        GeometryReader { geo in
            if mainData.animateClouds {
                Image("cloudsBlurry")
                    .resizable()
                    .scaledToFit()
                    .offset(x: self.cloudOffset, y: 0.0)
                    .onAppear {
                        let baseAnimation = Animation.linear(duration: 30)
                        let repeated = baseAnimation.repeatForever(autoreverses: true)

                        withAnimation(repeated) {
                            self.cloudOffset += geo.size.width * 0.50 //Error here
                        }
                    }
                Image("cloudsBlurry3")
                    .resizable()
                    .aspectRatio(contentMode: .fit)
                    .frame(height: geo.size.height * 2)
                    .offset(x: self.cloudOffset2, y: 0.0)
                    .onAppear {
                        let baseAnimation = Animation.linear(duration: 30)
                        let repeated = baseAnimation.repeatForever(autoreverses: true)
                        
                        self.cloudOffset2 = -geo.size.width //Error here
                        
                        withAnimation(repeated) {
                            self.cloudOffset2 += geo.size.width * 0.50 //Error here
                        }
                    }
            } else {
                Image("cloudsBlurry")
                    .resizable()
                    .scaledToFit()
                    .offset(x: 0.0, y: 0.0)
            }
        }
    }
}

1 个答案:

答案 0 :(得分:0)

您有周期,因为offset(x: self.cloudOffset依赖性和self.cloudOffset += geo由于上述依赖性而强制刷新。

尝试进行一些延迟更新,以使当前刷新以当前偏移值结束:

withAnimation(repeated) {
    DispatchQueue.main.async {
       self.cloudOffset += geo.size.width * 0.50
    }
}