Hallo,
I am trying to write a slightly generic view for user to enter weights in different units (there is a textfield and picker for the units), but I am not able to pass in the data in correct format. Can you please advise on how to resolve this?
import SwiftUI
//Mock data object, real one has more properties
class PersonalData: ObservableObject
{
@Published var weight: Measurement<UnitMass>?
init(_ weight: Double)
{
self.weight = Measurement(value: weight, unit: .kilograms)
}
}
//Mock data object, real one has more properties
class ToolData: ObservableObject
{
@Published var payload: Measurement<UnitMass>?
}
// My "generic" view to handle user input of weight
struct EntryFieldView: View
{
private let kg = UnitMass.kilograms
private let pounds = UnitMass.pounds
private var nf: NumberFormatter
{
let result = NumberFormatter()
result.maximumFractionDigits = 1
result.numberStyle = .none
return result
}
private var mf: MeasurementFormatter
{
let result = MeasurementFormatter()
result.unitOptions = .providedUnit
result.unitStyle = .medium
return result
}
@Binding var mass: Measurement<UnitMass>? //this seems to be the issue
@State var currentUnit : UnitMass = (Locale.current.usesMetricSystem ? .kilograms : .pounds)
private var valueBinding: Binding<Double>
{
Binding(
get:
{
mass!.value
},
set:
{ newVal in
mass!.value = newVal
})
}
var entry: some View
{
VStack{
if self.mass == nil
{
Button("+"){
mass = Measurement(value: 0, unit: currentUnit)
}
}
else
{
TextField("Weight", value: valueBinding, formatter: nf)
}
}
}
var unitPicker: some View
{
VStack{
Picker("\(mf.string(from: currentUnit))", selection: $currentUnit){
Text(mf.string(from: kg)).tag(kg)
Text(mf.string(from: pounds)).tag(pounds)
}.onChange(of: currentUnit, perform: { value in
mass?.convert(to: currentUnit)
}).pickerStyle(SegmentedPickerStyle())
.disabled(mass == nil)
}
}
var body: some View
{
HStack
{
entry
unitPicker
}
}
}
struct MasterView: View
{
@EnvironmentObject var person: PersonalData
@EnvironmentObject var tool : ToolData
var body: some View
{
NavigationView
{
VStack
{
NavigationLink(
destination: EntryFieldView(mass: Binding(person.weight), currentUnit: .kilograms), //+++++ HERE I GET ERROR
label: {
Text("Person weight: \(person.weight?.description ?? "none")")
})
NavigationLink(
destination: EntryFieldView(mass: Binding(tool.payload), currentUnit: .kilograms), //+++++ HERE I GET ERROR
label: {
Text("Tool payload: \(tool.payload?.description ?? "none")")
})
}.navigationTitle("Master")
}
}
}
struct MasterView_Previews: PreviewProvider {
static var previews: some View {
MasterView()
.environmentObject(PersonalData(80))
.environmentObject(ToolData())
}
}
The error I get is: "cannot convert value of type 'Measurement<UnitMass>?' to expected argument type 'Binding<Measurement<UnitMass>>'"
thank you for any help, I am sure there has to be an elegant way how to do this but I could not find one.