Swiftui-environmentobjectをパラメーターとして使用して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

回答:


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、

しかし、毎回まったく新しいViewObjectを作成せずに、ViewObject内でuserDataを操作したい場合はどうでしょうか。
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) }
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.