Swiftui-如何使用环境对象作为参数来初始化observedObject?


9

我不确定这是否是我们生活在这个勇敢的新SwiftUI世界中的反模式,但是从本质上来说,我有一个@EnvironmentObject,其中保存了一些我的视图可以调用的基本用户信息。

我还有一个@ObservedObject,它拥有此视图所需的一些数据。

当视图出现时,我想使用该@EnvironmentObject初始化@ObservedObject:

struct MyCoolView: View { 

    @EnvironmentObject userData: UserData
    @ObservedObject var viewObject: ViewObject = ViewObject(id: self.userData.UID)  

    var body: some View { 
            Text("\(self.viewObject.myCoolProperty)")
    } 
}

不幸的是,直到初始化后,我才能在环境变量上调用self:

“不能在属性初始化程序中使用实例成员'userData';属性初始化程序在'self'可用之前运行。”

我可以看到一些可能的前进路线,但是它们都像黑客一样。我应该如何处理?


也许您可以尝试init向该结构添加自定义。
nayem

我尝试了一下,但遇到了一个奇怪的错误: Property wrappers are not yet supported on local properties 基本上它说我不能在init方法中创建@ObservedObject。
snarik '19

Answers:


9

这是方法(最简单的IMO):

struct MyCoolView: View {
    @EnvironmentObject var userData: UserData

    var body: some View {
        MyCoolInternalView(ViewObject(id: self.userData.UID))
    }
}

struct MyCoolInternalView: View {
    @EnvironmentObject var userData: UserData
    @ObservedObject var viewObject: ViewObject

    init(_ viewObject: ViewObject) {
        self.viewObject = viewObject
    }

    var body: some View {
            Text("\(self.viewObject.myCoolProperty)")
    }
}

太棒了。MyCoolView实际上是我声明ObservedObject的“主”视图的子级。谢谢!
snarik '19

但是,如果您想在ViewObject内部操作userData而又不每次都创建一个全新的ViewObject,该怎么办?
BobiSad

0

"ViewObject"除了创建子视图,您还可以在其中添加一个虚拟的初始化器,以便您可以在调用真实的初始化器之前对其进行调用

struct MyCoolView: View { 

    @EnvironmentObject userData: UserData
    @ObservedObject var viewObject: ViewObject

    init() {
        viewObject = ViewObject()
        defer {
            viewObject = ViewObject(id: self.userData.UID)
        }
    }

    var body: some View { 
            Text("\(self.viewObject.myCoolProperty)")
    } 
}

为了记录我还没有测试


0

这是一个简单的方法:

struct MyCoolView: View {
    @EnvironmentObject var userData: UserData

    var body: some View {
        Observe(obj: ViewObject(id: userData.UID)) { viewObject in
             Text("\(viewObject.myCoolProperty)")
        }
    }
}

使用此帮助程序可以使其工作:

struct Observe<T: ObservableObject, V: View>: View {
    @ObservedObject var obj: T
    let content: (T) -> V
    var body: some View { content(obj) }
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.