Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Two-way binding in Swift Combine

I have a progress bar and a text field, both are updated depending on each other's input:

class ViewModel: ObservableObject {
    @Published var progressBarValue: Double {
        didSet {
            textFieldValue = String(progressBarValue)
        }
    }
    @Published var textFieldValue: String {
        didSet {
            progressBarValue = Double(progressBarValue)
        }
    }
}

Since updating one updates the other, I end up having an infinite recursion in my code.

Is there a way to workaround this with Combine or plain swift code?

like image 565
ldiqual Avatar asked Nov 06 '25 16:11

ldiqual


1 Answers

Expanding on my comment, here is a minimal example of a slider and a textfield that both control (and be controlled by) a value via two-way bindings:

class ViewModel: ObservableObject {
    @Published var progress: Double = 0
}

struct ContentView: View {
    @EnvironmentObject var model: ViewModel

    var body: some View {
        VStack {
            TextField("", value: self.$model.progress, formatter: NumberFormatter())
            Slider(value: self.$model.progress, in: 0...100)
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
            .environmentObject(ViewModel())
    }
}

Note that I also had to inject a ViewModel instance to my environment on AppDelegate in order for this to work (both on preview & actual app)

like image 105
Alladinian Avatar answered Nov 09 '25 09:11

Alladinian



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!