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

问题描述

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

据我所知,从.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)
            }
        }
    }
}

标签: swiftswiftui

解决方案


您有循环,因为offset(x: self.cloudOffset依赖并self.cloudOffset += geo由于上述依赖而强制刷新。

尝试稍微延迟进行更新,以使当前刷新以当前偏移值完成:

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

推荐阅读