Cannot convert value of type 'Binding<Double>' to expected argument type 'Binding<Double?>'

Viewed 6167

Sometimes I want to pass a value into @Binding property, and sometimes I do not want.

struct ParentView: View {
    @State var prop = 0.0

    var body: some View {
        ChildView(prop: $prop) // Error: Cannot convert value of type 'Binding<Double>' to expected argument type 'Binding<Double?>'
        ChildView() // sometimes I do not want pass anything
    }
}

struct ChildView: View {
    @Binding var prop: Double?

    init(prop: Binding<Double?> = .constant(nil)) {
        _prop = prop
    }

    var body: some View {
        Text("Child View")
    }
}

The solution may be following code.

@State var prop: Double? = 0.0

But, if possible, I don't want to define @State property as an Optional type.
Is there any other way?

2 Answers

Make the constant 0.

@Binding var prop: Double

init( prop: Binding<Double> = .constant(0) ) {
  _prop = prop
}

Here is a solution that allows to disambiguate w/ and w/o value binding.

Tested with Xcode 11.4 / iOS 13.4

struct ChildView: View {
    @Binding var prop: Double?

    init() {
        _prop = .constant(nil)
    }

    init(prop: Binding<Double>) {
        _prop = Binding(prop)
    }

    var body: some View {
        Group {
            if prop != nil {
                Text("Child View: \(prop!)")
            } else {
                Text("Child View")
            }
        }
    }
}
Related