Issue
Here is my code:
ForEach(StaffList, id: \.self) { item in
HStack {
Text("\(item)")
Spacer(minLength: 0)
Image(systemName: "x.circle")
.foregroundColor(.red)
.onTapGesture {
//TODO: Remove user UUID from array + Show add button
}
Image(systemName: "checkmark.circle")
.foregroundColor(.blue)
.onTapGesture {
//TODO: Add user UUID from array + Show remove button
}
}
}
A simple solution would be one @state variable in the Struct for every one in the loop, but it arises a problem. Because each button is assigned to the same variable. When the variable changes, all of them change. For example:
@State var isShowing = false
ForEach(StaffList, id: \.self) { item in
HStack {
Text("\(item)")
Spacer(minLength: 0)
if isShowing {
Image(systemName: "x.circle")
.foregroundColor(.red)
.onTapGesture {
//TODO: Remove user UUID from array + Show add button
is Showing = true
}
} else {
Image(systemName: "checkmark.circle")
.foregroundColor(.blue)
.onTapGesture {
//TODO: Add user UUID from array + Show remove button
isShowing = false
}
}
}
}
Technically this works, but take into consideration the unlimited amount of people in StaffList
. If I click X
on one of them, they would all update to show a Checkmark
. The goal is ForEach, they all have their own set of changes if that makes since. So when I click X
on one of them, it updates and shows the Checkmark
but none of the others in the ForEach loop update, and still show the X
.
Solution
Edit
After the latest update in the question, here’s the corrected answer to address the issue "Buttons are changing for all items rather than for each single item"
You can hide or show the buttons using an @State
variable. There are several tutorials online.
But to change the buttons for each single member of StaffList
separately (which we’d better call staffList
since it’s a variable), you need to have one @State
variable for each item in the ForEach
. This can be achieved by creating a secondary view, which in the example below I called ItemView
.
Here’s the code:
struct YourMainView: View {
// This is not the right place for the @State variable that affects each single item
// @State var isShowing = false
// Other variable declarations
var body: some View {
ForEach(staffList, id: \.self) { item in
ItemView(item: item)
}
}
}
// This is the view of each single item
struct ItemView: View {
let item: StaffListItemType // Whatever the actual type is
// Here is the right place to manage it (always make it private)
@State private var isShowing = false
var body: some View {
HStack {
Text("\(item)")
Spacer(minLength: 0)
if isShowing {
Image(systemName: "x.circle")
.foregroundColor(.red)
.onTapGesture {
//TODO: Remove user UUID from array + Show add button
isShowing = false // If it's true, it needs to become false. Or, use .toggle()
}
} else {
Image(systemName: "checkmark.circle")
.foregroundColor(.blue)
.onTapGesture {
//TODO: Add user UUID from array + Show remove button
isShowing = true // If it's false, it needs to become true. Or, use .toggle()
}
}
}
}
}
Answered By – HunterLion
Answer Checked By – Jay B. (BugsFixing Admin)