Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why Can't I Append to a State Array Within View in SwiftUI?

I'm not sure why this code doesn't work. It builds and runs fine, but nothing is displayed in the view. While debugging, I can see that the append() calls don't actually add the items to the array, but there's no error:

import SwiftUI

struct Test: View {
    @State private var array: [String] = []

    var body: some View {
        self.array.append("A")
        self.array.append("B")
        self.array.append("C")

        return VStack {
            ForEach(self.array, id: \.self) {string in
                Text(string)
            }
        }
    }
}

struct Test_Previews: PreviewProvider {
    static var previews: some View {
        Test()
    }
}

I've also tried doing the appends in an init(_:) with the same result. It works if I initialize the array with the values like @State private var array: [String] = ["A", "B", "C"] so it seems like there's some immutability of state variables nuance that I'm missing. I'm pretty new to Swift. Can someone please explain what I'm doing wrong here?

like image 880
twesque Avatar asked May 01 '20 16:05

twesque


1 Answers

I tried to run your code on Xcode 11.4.1, I got a warning saying;
Modifying state during view update, this will cause undefined behavior

This error occurs because you’re trying to modify the state of a SwiftUI view while it is actually being rendered.

So as an alternative you can try appending items in onAppear block

struct Test: View {

    State private var array: [String] = []

    var body: some View {
        VStack {
            ForEach(self.array, id: \.self) {string in
                Text(string)
            }
        }.onAppear { // Prefer, Life cycle method
            self.array.append("A")
            self.array.append("B")
            self.array.append("C")
        }
    }
}

Then you'll be able to see your items in the screen.

Also here is a bit detailed explanation

like image 100
Enes Karaosman Avatar answered Sep 21 '22 19:09

Enes Karaosman