Reputation: 1
I want extend Binding extension with a func that we can convert an optional Binding to a non-optional Binding and use it as a normal Binding. I almost could finish it but xCode through an error which I cannot handle it, I think I done everything correct.
extension Binding {
mutating func safeBinding<T>(defaultValue: T) -> Binding<T> where Value == Optional<T> {
let safeValue: T
if let unwrappedValue: T = self.wrappedValue { safeValue = unwrappedValue }
else { safeValue = defaultValue }
return Binding.init(get: { () -> T in return safeValue },
set: { (newValue) in self.wrappedValue = newValue })
}
}
The error:
Cannot convert return expression of type 'Binding<Optional<T>>' to return type 'Binding<T>'
extension Binding {
func safeBinding<T>(defaultValue: T) -> Binding<T> where Value == Optional<T> {
let safeValue: T
if let unwrappedValue: T = self.wrappedValue { safeValue = unwrappedValue }
else { safeValue = defaultValue }
return SwiftUI.Binding.init(get: { () -> T in return safeValue },
set: { (newValue) in self.wrappedValue = newValue })
}
}
Upvotes: 7
Views: 1383
Reputation: 52387
Binding
has an associated type Value
already, so by trying to use T
, you're putting a new generic on top of Value
, which already exists.
But, you will still end up using T
because you'll want to constrain Value
to scenarios where it is Optional:
extension Binding {
func safeBinding<T>(defaultValue: T) -> Binding<T> where Value == Optional<T> {
.init {
self.wrappedValue ?? defaultValue
} set: { newValue in
self.wrappedValue = newValue
}
}
}
As noted in the comments, the Xcode compiler has difficulty if just Binding.init
is used (note that I used just .init
). This can be solved by explicitly using Binding<T>.init
:
extension Binding {
func safeBinding<T>(defaultValue: T) -> Binding<T> where Value == Optional<T> {
Binding<T>.init {
self.wrappedValue ?? defaultValue
} set: { newValue in
self.wrappedValue = newValue
}
}
}
Upvotes: 9