How to bind Measurement with UI in SwiftUI?

Viewed 626

I'm trying to create a simple converter. Is there any chance I can bind Measurement() with the UI. Error says that in order to bind the Measurement in must be a string. Thank you in advance! Here is the code:

import SwiftUI
struct ContentView: View {
    @State private var tCelsius = Measurement(value: 0, unit: UnitTemperature.celsius)

    var fromCelsiusToFahrenheit: Measurement<UnitTemperature> {
        tCelsius.converted(to: .fahrenheit)
    }

    var body: some View {

        NavigationView {
            Form {
                TextField("Type the temperature", text: $tCelsius)
                Text("\(fromCelsiusToFahrenheit)")
            }

        }
    }
}
2 Answers

You need to create a custom Binding that converts your Measurement into a String.

You could improve below code by using a MeasurementFormatter for the conversion in the getter of temperatureBinding.

struct ContentView: View {
    @State private var tCelsius = Measurement(value: 0, unit: UnitTemperature.celsius)

    var fromCelsiusToFahrenheit: Measurement<UnitTemperature> {
        tCelsius.converted(to: .fahrenheit)
    }

    var body: some View {

        let temperatureBinding = Binding<String>(
            get: { self.tCelsius.description },
            set: { temperatureString in
                guard let newTemperature = Double(temperatureString) else { return }
                self.tCelsius.value = newTemperature
            }
        )

        return NavigationView {
            Form {
                TextField("Type the temperature", text: temperatureBinding)
                Text("\(fromCelsiusToFahrenheit)")
            }

        }
    }
}

Yes, you need to use one of the value-formatter constructors like this;

@State var min: Measurement<UnitMass> = Measurement(value: 0, unit: .pounds)

private var massFormatter = MeasurementFormatter()

var body: some View {
    TextField("Min", value: $min, 
                     formatter: massFormatter).keyboardType(.decimalPad)
}
Related