skip to Main Content

I have a list with items which are pulled from a firebase database. I would like individual counters for each item but one variable isn’t doing this for me and is adding 1 to each item on the list. Picture attached to show.

Code I have:

    @State var quantityItem: Int = 0
    var body: some View {
            List (menumodel.list) { item in
            VStack{
                HStack{
                    VStack {
                        Text(item.id)
                            .frame(maxWidth: .infinity, alignment: .leading)
                        Text("123 kcal, 330ml")
                            .font(.caption)
                            .foregroundStyle(Color.gray)
                            .frame(maxWidth: .infinity, alignment: .leading)
                        
                    }
                    .frame(maxWidth: .infinity, alignment: .leading)
                    .padding(.vertical)
                    HStack{
                        Button {
                            if quantityItem > 0 {
                                self.quantityItem -= 1
                            }
                            
                        }label: {
                            Image(systemName: "minus.circle")
                                .tint(Color.black)
                        }
                        Text("(quantityItem)")
                        Button {
                            self.quantityItem += 1
                        }label: {
                            Image(systemName: "plus.circle")
                                .tint(Color.black)
                        }
                    }.frame(maxWidth: .infinity, alignment: .trailing)
                        .padding(.all)
                }
            }
        }
        
        .listStyle(GroupedListStyle())
        .buttonStyle(BorderlessButtonStyle())
        
        
}
    }
#Preview {
    DrinksMenuView()
}```

2

Answers


  1. you need to use a dictionary to count items on each list

    @State private var quantities: [String: Int] = [:]
    

    change your buttons as follow:

     HStack {
                            Button {
                                decrementQuantity(for: item.id)
                            } label: {
                                Image(systemName: "minus.circle")
                                    .tint(Color.black)
                            }
                            Text("(quantities[item.id, default: 0])")
                            Button {
                                incrementQuantity(for: item.id)
                            } label: {
                                Image(systemName: "plus.circle")
                                    .tint(Color.black)
                            }
                        }
                        .frame(maxWidth: .infinity, alignment: .trailing)
                        .padding(.all)
    

    then use these:

       private func incrementQuantity(for id: String) {
                quantities[id, default: 0] += 1
            }
        
            private func decrementQuantity(for id: String) {
                if let currentCount = quantities[id], currentCount > 0 {
                    quantities[id]! -= 1
                }
            }
    
    Login or Signup to reply.
  2. You need to create a ListRow view that holds a variable for each item.

    E.g:

    struct ListRow: View {
        let item: Item
        
        @State private var quantityItem: Int = 0
    
        var body: some View {
    
            //...
    
        }
    }
    
    struct DrinksMenuView: View {
        var body: some View {
            List (menumodel.list) { item in
                ListRow(item: item)
            }
        }
    }
    

    Alternatively, as Hezy Ziv mentioned, if you need to use these variables outside the ListRow view you could use an array/dictionary that holds all variables.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search