与自定义@EnvironmentObject
一起使用时,我遇到以下Shape
的SwiftUI错误:
Fatal error: No ObservableObject of type MyObject found. A View.environmentObject(_:) for MyObject may be missing as an ancestor of this view.: file SwiftUI, line 0
只有当我使用任何Shape
方法返回实例的新副本(例如stroke()
)时,这种情况才会发生。
这里是一个Swift游乐场示例,可以重现:
import SwiftUI
import PlaygroundSupport
class MyObject: ObservableObject {
@Published var size: Int = 100
}
struct MyShape: Shape {
@EnvironmentObject var envObj: MyObject
func path(in rect: CGRect) -> Path {
let path = Path { path in
path.addRect(CGRect(x: 0, y: 0,
width: envObj.size, height: envObj.size))
}
return path
}
}
struct MyView: View {
var body: some View {
MyShape().stroke(Color.red) // FAIL: no ObservableObject found
// MyShape() // OK: it works
}
}
let view = MyView().environmentObject(MyObject())
PlaygroundPage.current.setLiveView(view)
由于似乎未复制环境字段,因此我也尝试过这样明确地做到这一点:
struct MyView: View {
@EnvironmentObject var envObj: MyObject
var body: some View {
MyShape().stroke(Color.red).environmentObject(self.envObj)
}
}
它仍然失败。作为SwiftUI的初学者,除了不使用环境之外,我不知道这是否是预期的行为,是否不继承视图层次结构环境以及如何处理它。
有什么主意吗?
答案 0 :(得分:4)
问题实际上是.stroke
在构造函数之后被称为 ,因此在注入environmentObject
之前(如果注释掉笔画,您可以测试它是否有效)。但是.stroke
不能在注入环境对象之后添加 ,因为.stroke
是Shape-only
修饰符。
解决方案是在构造过程中注入依赖项,如下所示。使用Xcode 11.4 / iOS 13.4进行了测试
struct MyShape: Shape {
@ObservedObject var envObj: MyObject
...
}
struct MyView: View {
@EnvironmentObject var envObj: MyObject
var body: some View {
MyShape(envObj: self.envObj).stroke(Color.red)
}
}