How to make an updatable ForEach loop SwiftUI

I have a ForEach loop in my code which is used to display text per child of an array (i think it's an array).

var flags: [String: Any] = [
    "Flag1": "FlagValue"
    // More values will go here, by default there are no values (but can be
    // loaded in)  
]

And this is my code

// CONTENT
    HStack {
        VStack {
            ForEach(0...flags.count, id: \.self) { flag in
                Text("hey")
               }
            }
         }

When I start the app there's only one "hey" and no more will show up when I add more flags.

Answered by CheeryCode in 803181022

I found that the solution to this problem would be to dismiss and re-open the ContentView

Hi, you are working with a dictionary type. you have some issues in your code:

This loop iterates from 0 to flags.count. flags.count returns 1 since there’s one item in the flags dictionary. But the loop will iterate from 0 to 1, meaning it will run two times, which may not be the intended behavior. This could lead to an off-by-one error.

AND: you are not showing the dictionary entry in your Text View. You have to iterate over your Dictionary-Type. You are showing just the constant "hey".

you have to change the code to something similar to: like ForEach(Array(flags.keys), id: \.self) and... Text("\(flag)")

would propose you go to doc about dictionary. https://docs.swift.org/swift-book/documentation/the-swift-programming-language/collectiontypes#app-top)

Thank you for your response, The "hey" constant was intended behaviour, and I tried your answer.

I noticed that it did indeed put the flag and only the flag in the view with no extra iterations, however it didn't update (what I wanted).

Also I was wondering how to get the flag value in the ForEach (there is no flag.value)

This was very helpful though!

When I start the app there's only one "hey" and no more will show up when I add more flags.

No, you get 2 heys, as explained by @B347

What you want is not clear at all.

  • what do you expect to get ?
  • display text per child: where are the children defined ?
  • where and how do you add flags ?

In any case, if you want view to be updated, flags should be a State var.

An advice: study an Apple tutorial on Swift and SwiftUI. It seems there are some basics you are still missing.

  • what do you expect to get ?
  • display text per child: where are the children defined ?
  • where and how do you add flags ?

I wanted the ForEach loop to update every time I added a value. What @B347 told me was helpful because I was able to reduce the amount of incorrect "hey"s added to my view, however did not solve the issue.

The children are defined in the same place you add flags. There's a seperate window which opens that allows users to enter flags and values (this works properly). This is a seperate file within the app, however the flags dictionary can be accessed from other files.

An advice: study an Apple tutorial on Swift and SwiftUI. It seems there are some basics you are still missing.

I have covered the basics many times, I would not call this basic however what I learnt may differ from what you did.

Thanks for the reply. What is needed is to see the complete code, to understand what you do and what is to be changed.

@Claude31 The ForEach is as follows (sorry about formatting):


            VStack {
                ForEach(Array(flags.keys), id: \.self) { flag in
                    HStack {
                        Spacer()
                        Button("Delete") {
                            print("delete \(flag)")
                        }.padding()
                        Toggle(isOn: $isActiveToggleOn) {}.padding().onChange(of: isActiveToggleOn) {
                            if isActiveToggleOn {
                                print("activate \(flag)")
                            } else {
                                print("deactivate \(flag)")
                            }
                        }
                        Spacer()
                        Text(flag).padding()
                        Spacer()
                        Text(flag).padding()
                        Spacer()
                    }
                }
            }

Thanks, but that's not enough to test code. We don't see var declarations, code to change the flags…

So, no way to help with so limited code.

@CheeryCode Could you please share a link to your test project. That'll help us better understand what's going on. If you're not familiar with preparing a test project, take a look at Creating a test project.

@DTS Engineer @Claude31 Hi again,

Since my project is going to be open readible the link can be found here: https://github.com/SunnyFloppyDiskStudios/FlopFlagger

Most relevant files are ContentView and AddFlagView

Accepted Answer

I found that the solution to this problem would be to dismiss and re-open the ContentView

How to make an updatable ForEach loop SwiftUI
 
 
Q