This is a funny side effect when using the inline view accessor like so:
class CowsOverview: ViewController {
@Published var search = ""
var view: some View {
TextField("Search it", $search) // <= doesn't work
}
This does work when using the ViewController via the environment, e.g.:
class CowsOverview: ViewController {
@Published var search = ""
struct ContentView: View {
@EnvironmentObject var viewController : CowsOverview
TextField("Search it", $viewController.search)
}
}
This is because the $ accesses the projectedValue of the property wrapper - @Published in the first case, and @EnvironmentObject in the second. And while @EnvironmentObject gives you a Binding (and then that goes on traversing keypathes), the @Published gives you the Combine Publisher for the property.
There are a few ways to solve this, either using a trampoline providing the Bindings, maybe like:
var `$`: Trampoline<Self, ... key path stuff>
or maybe just adding a .bind() to @Published, like:
extension Published {
var bind : Binding<Value> { ... }
}
Maybe someone has additional ideas. Generally it is not a huge deal, as one often ends up w/ real view structs anyways.
This is a funny side effect when using the inline
viewaccessor like so:This does work when using the ViewController via the environment, e.g.:
This is because the
$accesses theprojectedValueof the property wrapper -@Publishedin the first case, and@EnvironmentObjectin the second. And while@EnvironmentObjectgives you a Binding (and then that goes on traversing keypathes), the@Publishedgives you the CombinePublisherfor the property.There are a few ways to solve this, either using a trampoline providing the Bindings, maybe like:
or maybe just adding a
.bind()to@Published, like:Maybe someone has additional ideas. Generally it is not a huge deal, as one often ends up w/ real view structs anyways.