如果我添加一个EnviromentObject
属性包装器,则Xcode预览不起作用。每当我添加一个画布时,画布都不会建立,并且出现此错误:
无法在此文件中预览-[应用名称] .app可能崩溃了
如果我将EnviromentObject
属性包装器替换为ObservedObject
并对其进行初始化,则一切正常。
这是我的代码:
class NetworkManager: ObservableObject {
}
struct ContentView : View {
@EnvironmentObject var networkManager: NetworkManager
var body: some View {
Text("Canvas not working")
}
}
#if DEBUG
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView().environmentObject(NetworkManager())
}
}
#endif
更新:
当我使用绑定时,它也不会加载预览:
struct ContentView : View {
@EnvironmentObject var networkManager: NetworkManager
@Binding var test123: String
var body: some View {
Text("Canvas not working")
}
}
#if DEBUG
struct ContentView_Previews: PreviewProvider {
@State static var test1 = ""
static var previews: some View {
ContentView(test123: $test1).environmentObject(NetworkManager())
}
}
#endif
答案 0 :(得分:5)
按照@graycampbell的建议,您需要确保将EnvironmentObject提供给SceneDelegate中的ContentView。尽管许多预览/画布机制都在黑框中,但Xcode的UI建议使用新的预览或刷新现有的预览,甚至为常规预览构建(或更新)应用变体的形式,例如反对“实时预览”。如果SceneDelegate的设置不正确,此过程可能会失败。
对于您的@Binding问题,Binding.constant(_ :)应该会有所帮助。根据{{3}} .constant执行以下操作:
创建一个具有不变值的绑定。
这是您要预览的内容,而不是示例代码显示的@State。您可以在SwiftUI Documentation的第3节中看到一个使用.constant的示例。
所以代替这个:
#if DEBUG
struct ContentView_Previews: PreviewProvider {
@State static var test1 = "Some Preview String"
static var previews: some View {
ContentView(test123: $test1)
.environmentObject(NetworkManager())
}
}
#endif
您可以执行以下操作:
#if DEBUG
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView(test123: .constant("Some Preview String"))
.environmentObject(NetworkManager())
}
}
#endif
有了此更改,您的代码预览对我来说非常完美。 请记住,您再次需要在SceneDelegate或使用此特定ContentView的任何其他位置为此Binding提供一个值。否则,您将遇到与EnvironmentObject面临的问题类似的问题,只是幸运的是,编译器错误突出了这一特殊的遗漏。
答案 1 :(得分:2)
我遇到了同样的问题,并且找出了原因。
我只是忘了添加.environmentObject()
修饰符
到预览部分中的ContentView()
。
struct Content_Previews: PreviewProvider {
static var previews: some View {
ContentView().environmentObject(NetworkManager())
}
}
这就是为什么Xcode在不显示代码错误的情况下构建它的原因, 但在画布上预览时崩溃。 -简单的错误,我知道。
答案 2 :(得分:1)
我根据您提供的代码假设SceneDelegate
如下所示:
if let windowScene = scene as? UIWindowScene {
let window = UIWindow(windowScene: windowScene)
window.rootViewController = UIHostingController(rootView: ContentView())
self.window = window
window.makeKeyAndVisible()
}
我不会假装我确切地知道画布在生成预览时在幕后正在做什么,但是基于该错误专门指出该应用程序可能崩溃的事实,我假设它是在尝试生成预览时尝试启动整个应用程序。也许它需要使用SceneDelegate
来启动预览,也许完全是另外一回事-我不能肯定地说。
无论如何,应用程序崩溃的原因是您没有在SceneDelegate
中传递环境对象。您的SceneDelegate
应该如下所示:
if let windowScene = scene as? UIWindowScene {
let window = UIWindow(windowScene: windowScene)
window.rootViewController = UIHostingController(rootView: ContentView().environmentObject(NetworkManager()))
self.window = window
window.makeKeyAndVisible()
}
答案 3 :(得分:0)
答案 4 :(得分:0)
我确实有一个解决方法,但是是的,该错误确实在XCode中。
要解决此问题。您必须先设置SceneDelegate
。
if let windowScene = scene as? UIWindowScene {
let window = UIWindow(windowScene: windowScene)
window.rootViewController = UIHostingController(rootView: ContentView().environmentObject(NetworkManager()))
self.window = window
window.makeKeyAndVisible()
}.
您还必须设置预览。看来您已经做到了。
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView().environmentObject(NetworkManager())
}
}.
最后,只需在@State
内声明一个ContentView
和@Published
类型相同的@EnvironmentObject
变量,无论是否将其用于绑定到ContentView
没关系。
@State var bindingVar: Double = 0.0
正如我之前所说的,这是XCode错误,我不知道为什么ContentView
需要一个相同类型的@State变量来开始预览@EnvironmentObject
绑定的代码。
可能ContentView_Previews
无法从@EnvironmentObject
中找到绑定。
您可以在我的代码下面看到它,它像一个超级按钮。