Fiser
(Fiser)
1
Hi guys, I've been stuck at this point for a while and I don't know if it's because of an unpacking limitation or that I'm doing something wrong.
To start with I have a Template which is a protocol that has an associated type which is a View.
I am having a complication with the existential types at the time of doing the unpacking when the type is inside a SwiftUI Binding with the structure that I have explained, here the code.
@Binding var input: any InputTemplate
var body: some View {
self.SomeInputBar(self.$input)
}
private func SomeInputBar<T: InputTemplate>(_ input: Binding<T>) -> AnyView {
AnyView(
T.InputBar(
input: input
)
)
}
The compiler gives me the following error
Type 'any InputTemplate' cannot conform to 'InputTemplate'
I have fixed it as follows but I don't like the solution at all
@Binding var input: any InputTemplate
var body: some View {
self.SomeInputBar(self.input)
.task {
state.executeOnAppearEvent(input: input)
}
.id(input.id)
}
private func SomeInputBar<T: InputTemplate>(_ input: T) -> AnyView {
AnyView(
T.InputBar(
input: Binding(
get: { input },
set: { self.input = $0 }
)
)
)
}
Could one of you help me with this? I think there's something I'm not understanding.
bbrk24
2
I believe that binding generic types doesn't work. For example, it should be relatively clear why this won't work:
func sum<T: AdditiveArithmetic>(arr: Array<T>) -> T {
return arr.reduce(into: T.zero, +=)
}
let myArray: Array<any AdditiveArithmetic> = [(1 as Int), (2.0 as Double)]
_ = sum(arr: myArray) // What is T? It can't be Int nor Double
Currently, the type system has no way to encode whether it's possible to do the Foo<any Bar> -> Foo<some Bar> transformation, so the compiler conservatively assumes that it never is.
Would it be possible to make the view itself generic over the input type?
struct EnclosingView<T: InputTemplate>: View {
@Binding var input: T
var body: some View {
someInputBar($input)
}
private func someInputBar(_ input: Binding<T>) -> AnyView {
// ...
}
}
1 Like
Fiser
(Fiser)
3
Thanks for the explanation, that makes sense,
But the example you have given just moves the problem up, at some point I have to convert the any into some somewhere and it has to be inside a Binding.
It really comes from an array, so it can't be opaque, it has to be an existential type and somewhere have to be the unboxing.
Fiser
(Fiser)
4
Ok, I have seen that the optional type also has this limitation too
, it is a pity, it is a very big limitation in the potential of my code.
Edit:
I tried even this approach without expectatives, but does not work neither
I tried doing it using as? but neither
self.input as? Binding
but doesnt work neither should work it, but the compiler said that
Cast from 'any InputTemplate' to unrelated type 'Binding' always fails
Cast from 'Binding' to unrelated type 'Binding' always fails
But I think the as? should have worked, I was very surprised it didn't work.
Any clue about that please?