问题
I want to inject an EnvironmentObject while creating a SwiftUI view in watchOS6.
But since WKHostingController expects a Concrete type I am not able to do the following ContentView().environmentObject(UserData())
class HostingController: WKHostingController<ContentView> {
override var body: ContentView {
return ContentView().environmentObject(UserData())
}
}
This code fails with the following error:
Cannot convert return expression of type 'some View' to return type 'ContentView'
I have seen workaround like this : Using environmentObject in watchOS this seems like a hack instead of a proper solution.
I asked a watchOS engineer on Twitter regarding the same and his reply was to place .environmentObject(UserData())
inside the body of ContentView()
. I tried doing that but Xcode reports an error.
So has anyone found a way to do the same ?
回答1:
The workaround from the link uses AnyView
, which is a very bad idea. It has been explained in several other questions and tweets from Apple engineers, that AnyView should only be used on leaf views, as there is a heavy performance hit otherwise.
As for the second option (put the environmentObject
inside ContentView
), it works fine. Here you have an example:
class UserData: ObservableObject {
@Published var show: Bool = true
}
struct ContentView: View {
@State var model = UserData()
var body: some View {
SubView().environmentObject(model)
}
}
struct SubView: View {
@EnvironmentObject var model: UserData
var body: some View {
VStack {
Text("Tap Me!").onTapGesture {
self.model.show.toggle()
}
if self.model.show {
Text("Hello World")
}
}
}
}
来源:https://stackoverflow.com/questions/57559200/how-to-inject-environmentobject-in-watchos6