【问题标题】:How do you fix "Cannot use mutating member on immutable value: 'self' is immutable"?你如何解决“不能在不可变值上使用变异成员:'self'是不可变的”?
【发布时间】:2020-09-15 04:13:26
【问题描述】:

如何解决错误Cannot use mutating member on immutable value: 'self' is immutableself.prepareConfetti(screenWidth: CGFloat(geo.size.width)) 行上?

关于这个主题有很多 StackOverflow 问题,但没有一个对我有帮助。

我的代码:

struct ContentView: View {
    @State private var confettiTimer = Timer.publish(every: 0.0166, on: .main, in: .common).autoconnect()
    private var confettiX = [CGFloat]()
    private var confettiY = [CGFloat]()
    private var confettiWidth = [CGFloat]()
    private var confettiHeight = [CGFloat]()
    private let numOfConfetti: Int = 80
 
    var body: some View {
        GeometryReader { geo in
            ForEach(0..<self.confettiY.count, id: \.self) { i in
                Path { path in
                    path.addRect(
                        CGRect(
                            x: self.confettiX[i],
                            y: self.confettiY[i],
                            width: self.confettiWidth[i],
                            height: self.confettiHeight[i]
                        )
                    )
                }
                .fill(Color.black)
                .onAppear {
                    self.prepareConfetti(screenWidth: CGFloat(geo.size.width)) //This gives the error
                }
                .onReceive(self.confettiTimer) { time in
                    
                }
            }
        }
    }
    
    mutating func prepareConfetti(screenWidth: CGFloat) {
        for _ in 0..<self.numOfConfetti {
            let x: CGFloat = 0.0
            let y = screenWidth * 0.5
                
            self.confettiX.append(x)
            self.confettiY.append(y)
            self.confettiWidth.append(20.0)
            self.confettiHeight.append(20.0)
        }
    }
    
}

【问题讨论】:

    标签: swift swiftui


    【解决方案1】:

    你不能以这种方式改变 SwiftUI 视图,你应该使用这些属性作为状态

    struct ContentView: View {
        @State private var confettiTimer = Timer.publish(every: 0.0166, on: .main, in: .common).autoconnect()
        
        @State private var confettiX = [CGFloat]()
        @State private var confettiY = [CGFloat]()
        @State private var confettiWidth = [CGFloat]()
        @State private var confettiHeight = [CGFloat]()
        private let numOfConfetti: Int = 80
     
        var body: some View {
            GeometryReader { geo in
                ForEach(0..<self.confettiY.count, id: \.self) { i in
                    Path { path in
                        path.addRect(
                            CGRect(
                                x: self.confettiX[i],
                                y: self.confettiY[i],
                                width: self.confettiWidth[i],
                                height: self.confettiHeight[i]
                            )
                        )
                    }
                    .fill(Color.black)
                    .onAppear {
                        self.prepareConfetti(screenWidth: CGFloat(geo.size.width)) //This gives the error
                    }
                    .onReceive(self.confettiTimer) { time in
                        
                    }
                }
            }
        }
        
        private func prepareConfetti(screenWidth: CGFloat) {
            for _ in 0..<self.numOfConfetti {
                let x: CGFloat = 0.0
                let y = screenWidth * 0.5
                    
                self.confettiX.append(x)
                self.confettiY.append(y)
                self.confettiWidth.append(20.0)
                self.confettiHeight.append(20.0)
            }
        }
    }
    

    【讨论】:

    • 用 Xcode 11.7 / iOS 13.7 测试 - 编译和运行没有错误,行为超出范围。
    • 很抱歉我之前的评论说它不起作用。我的错。它确实有效。谢谢! :)
    猜你喜欢
    • 1970-01-01
    • 2020-01-28
    • 1970-01-01
    • 1970-01-01
    • 2020-10-23
    • 2020-08-08
    • 2020-07-27
    • 2020-07-01
    • 1970-01-01
    相关资源
    最近更新 更多