BSR
BSR

Reputation: 57

Binding a Stepper with a Dictionary SwiftUI

I'm not sure if this is possible but I'm currently trying to create a list of steppers using a dictionary[String: Int]. Using the stepper I'm hoping to change the qty amount in the dictionary. I tried binding the value to the stepper by first doing $basic[name] and then that didn't work and so I ended up with $basic[keyPath: name] which resulted in fewer errors but still wasn't working. In the beginning I was having problems of not wanting to change the order of the dictionary that I made, and so I ended up with the ForEach below which worked for not changing the order of dictionary, however, I'm wondering if that's one of the reasons that the binding isn't working.

    import SwiftUI
    
    struct AllSuppliesStruct {
        @State var basic = ["Regular Staples": 0, "Big Staples": 0]
    
    
        var body: some View {
            Form {
                //Basic Supplies
                ForEach(basic.sorted(by: >), id: \.key) { name, qty in
                    Stepper("\(name), \(qty)", value: $basic[keyPath: name], in: 0...10)
                           }
            }
        }
    }

Goal: If I pressed on the stepper only once for both Regular and Big Staples then I expect this in the dictionary

basic = ["Regular Staples": 1, "Big Staples": 1]

Upvotes: 1

Views: 357

Answers (2)

Mantosh Kumar
Mantosh Kumar

Reputation: 273

We can use this way to add Stepper with custom steps in SwiftUI

 import SwiftUI
      
    struct ContentView: View {
        
        @State private var sleepAmount = 8.0
        @State private var coffeAmount = 1
        
        var body: some View {
            
            NavigationStack {
                Form {
                    Text("Desired amount of sleep:").font(.headline)
                    Stepper("\(sleepAmount.formatted()) hours", value: $sleepAmount, in: 4...12, step: 0.25)
                    
                    Text("Daily coffee intake:").font(.headline)
                    Stepper("\(coffeAmount) cup (S)", value: $coffeAmount, in: 2...10, step: 1)
                }
                .navigationTitle("Mantosh App")
            }
            
        }
    }
    
    #Preview {
        ContentView()
    }

Upvotes: 0

Fabio Felici
Fabio Felici

Reputation: 2906

You can manually create a Binding that acts on basic and pass that to Stepper:

struct AllSuppliesStruct: View {
  @State var basic = ["Regular Staples": 0, "Big Staples": 0]

  var body: some View {
    Form {
      ForEach(basic.sorted(by: >), id: \.key) { name, qty in
        Stepper(
          "\(name), \(qty)",
          value: .init(
            get: { basic[name]! },
            set: { basic[name] = $0 }
          ),
          in: 0...10
        )
      }
    }
  }
}

Upvotes: 2

Related Questions