0

I have two Published state in my viewmodel one is for source and another one is for destination

Based on the solution here to detect live changes on textfield. I have implemented like this

TextField("", text: $viewModel.source)
TextField("", text: $viewModel.destination)

Problem, here is i need to update the either fields whenever user enter some value. For example - If user enter on source then i need to update destination with source inputs. And if user input destination then need to update source.

@Published var source: Double = 0 {
        didSet {
            destination = source / rate
        }
    }

This is just one solution. I have to repeat it same for destination then it will create deadlock

@Published var destination: Double = 0 {
        didSet {
            source = destination * rate
        }
    }

How to solve this problem ? Only solution i imagine if there is any way i can get live changes in the form of callback then i can update the either field but i don't know if it is possible

Tariq
  • 9,861
  • 12
  • 62
  • 103

1 Answers1

0

Here is possible solution. Tested with Xcode 11.4 / iOS 13.4

demo

class SourceDestinationViewModel: ObservableObject {
    let rate: Double = 2 // just for demo
    
    @Published var source: Double = 0 {
        didSet {
            let newValue = source / rate
            if destination != newValue {
                destination = newValue
            }
        }
    }

    @Published var destination: Double = 0 {
        didSet {
            let newValue = destination * rate
            if source != newValue {
                source = newValue
            }
        }
    }
}

struct TestDependentFields: View {
    @ObservedObject var vm = SourceDestinationViewModel()

    var body: some View {
        VStack {
            TextField("", text: Binding<String>(get: { String(self.vm.source) },
                set: { self.vm.source = ($0 as NSString).doubleValue }))
            TextField("", text: Binding<String>(get: { String(self.vm.destination) },
                set: { self.vm.destination = ($0 as NSString).doubleValue }))

            Spacer()
        }
    }
}
Asperi
  • 228,894
  • 20
  • 464
  • 690