首页 > 解决方案 > 在 SwiftUI 中找不到子形状的 EnvironmentObject

问题描述

@EnvironmentObject与自定义 , 一起使用时,我遇到以下 SwiftUI 错误Shape

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 初学者,我不知道这是否是预期的行为,不继承视图层次环境,以及如何处理它 - 除了不使用环境。

任何想法?

标签: swiftui

解决方案


问题实际上是在构造函数之后.stroke调用,所以在注入之前(如果你注释掉笔划,你可以测试它是否有效)。但是在环境对象注入不能添加,因为是修饰符。environmentObject.stroke.strokeShape-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)
    }
}

推荐阅读