EnvironmentObject не найден для дочернего Shape в SwiftUI - PullRequest
1 голос
/ 15 апреля 2020

Я сталкиваюсь со следующей ошибкой SwiftUI с @EnvironmentObject при использовании с пользовательским 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, я не знаю, является ли это ожидаемым поведением, а не наследованием среды иерархии представлений и как с ней обращаться - кроме как без использования среды.

Есть идеи?

1 Ответ

1 голос
/ 15 апреля 2020

Проблема на самом деле в том, что .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)
    }
}
...