I have an init like so:
@Binding var height: Double?
init(height: Binding<Double?>? = nil) {
self._height = height
}
I am getting an error:
Value of optional type 'Binding<Double?>?' must be unwrapped to a value of type 'Binding<Double?>'
What would be the correct syntax so that I would not need to pass any value in init if it's not needed, but if I did pass the height it would then assign to the local binding variable?
Thanks.
CodePudding user response:
The process of "converting" an optional to a non-optional is unwrapping. The only way you can convert an optional to a non-optional is to provide some default value in the case where the optional is nil
.
You have got a little confused about Swift optional
vs default parameters.
Your problem here is you want your height
argument to be optional (as in the caller doesn't need to specify it), but you shouldn't declare it as an optional
because your object needs there to be an instance of a Binding
- the binding must exist even though its wrapped value may be nil
.
The type wrapped in the binding is an optional Double
and that is what you need to provide as a default value - a binding to a Double?
. You can do this with Binding.constant
struct SomeView {
@Binding var height: Double?
init(height: Binding<Double?> = .constant(nil)) {
self._height = height
}
}
Now your default value is a binding to a Double?
and the wrapped value is nil
If you did want your caller to be able to explicitly pass nil
for the height
binding then you have to deal with the default value in the initialiser itself:
struct SomeView {
@Binding var height: Double?
init(height: Binding<Double?>? = nil) {
self._height = height ?? .constant(nil)
}
}
CodePudding user response:
There won't ever be a need to pass a binding to an optional. What you actually want is to be able to handle these two cases:
init(height: Binding<Double>) {
_height = .init(height)
}
init() {
_height = .constant(nil)
}
Which is closely emulated by using a default value:
init(height: Binding<Double>? = nil) {
_height = height.map(Binding.init) ?? .constant(nil)
}