SeanForReal
SeanForReal

Reputation: 141

Disable button from loop when clicked

Currently I have a foreach loop bring in a list of items, each with a button that performs a function. How do I disable an individual button when clicked, for only the single user without using user accounts? Thanks so much in advance!

Extra context: Each item has what is essentially an "Add" button, that adds +1 to a field in the db, each user should only be allowed to press the button once, therefore I need to disable it after one click. As of right now, they can click it as many times as they want the number in the db will keep going up.

Code

ForEach(items.indices, id: \.self) { i in
HStack {
   Text(items[i].name)
   Spacer()
   Button(action: {
      self.performFunction()
      }) {
          Text("Yes")
             .font(.system(size: 14))
             .foregroundColor(Color.white)
             .padding(.horizontal)
       }
   }
}

Upvotes: 0

Views: 287

Answers (2)

Leon Vladimirov
Leon Vladimirov

Reputation: 141

Assuming "Item" is a struct or a class you can always just add a boolean flag to indicate if this item was selected.

So, for example, something like this:

struct Item {
    var name: String
    var selected: Bool = false
}

struct ContentView: View {
    @State private var items: [Item] = [
        Item(name: "Bob"),
        Item(name: "Joe"),
        Item(name: "John Cena")
    ]
        
    var body: some View {
        ForEach(items.indices, id: \.self) { i in
            HStack {
                Text(items[i].name)
                Spacer()
                Button(action: {
                    items[i].selected.toggle()
                }) {
                    Text(items[i].selected ? "Yes" : "No")
                        .font(.system(size: 14))
                        .foregroundColor(.black)
                        .padding(.horizontal)
                }
            }
        }
    }
}

Upvotes: 1

Asperi
Asperi

Reputation: 257789

It is not clear the context... but the possible solution is to create array of same length as items and use it to store clicked state, like

@State private var clicked: [Bool]  // initiate with array of false when `items` ready

...

   Button(action: {
      self.performFunction()
      self.clicked[i] = true      // << here !!
      }) {
          Text("Yes")
             .font(.system(size: 14))
             .foregroundColor(Color.white)
             .padding(.horizontal)
       }
       .disabled(self.clicked[I])        // // << here !!

Upvotes: 0

Related Questions