Swiftui - Bagaimana cara menginisialisasi objek yang diamati menggunakan objek lingkungan sebagai parameter?


9

Saya tidak yakin apakah ini adalah antipattern dalam dunia SwiftUI baru yang berani yang kita tinggali ini, tetapi pada dasarnya saya memiliki @EnvironmentObject dengan beberapa informasi pengguna dasar yang tersimpan di dalamnya sehingga pandangan saya dapat dipanggil.

Saya juga memiliki @ObservedObject yang memiliki beberapa data yang diperlukan untuk tampilan ini.

Ketika tampilan muncul, saya ingin menggunakan @EnvironmentObject untuk menginisialisasi @ObservedObject:

struct MyCoolView: View { 

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

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

Sayangnya saya tidak dapat menyebut diri pada variabel lingkungan sampai setelah inisialisasi:

"Tidak dapat menggunakan instance anggota 'userData' dalam inisialisasi properti; inisialisasi properti dijalankan sebelum 'diri' tersedia."

Saya dapat melihat beberapa kemungkinan rute ke depan, tetapi semuanya terasa seperti retasan. Bagaimana saya harus mendekati ini?


Mungkin Anda bisa mencoba menambahkan custom initke struct.
nayem

Saya mencobanya dan mendapat kesalahan yang agak aneh: Property wrappers are not yet supported on local properties Pada dasarnya ini mengatakan saya tidak dapat membuat @ObservedObject dengan metode init.
snarik

Jawaban:


9

Inilah pendekatannya (IMO paling sederhana):

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)")
    }
}

Ini sempurna. MyCoolView sebenarnya adalah anak dari tampilan 'rumah' tempat saya mendeklarasikan ObservedObject. Terima kasih!
snarik

Tetapi bagaimana jika Anda ingin memanipulasi data user di dalam ViewObject tanpa ViewObject yang sama sekali baru dibuat setiap saat?
BobiSad

0

alih-alih membuat subview Anda bisa menambahkan inisialisasi dummy ke Anda "ViewObject"sehingga Anda dapat memanggilnya sebelum memanggil inisialisasi nyata

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)")
    } 
}

untuk catatan saya belum mengujinya


0

Ini cara mudah untuk melakukannya:

struct MyCoolView: View {
    @EnvironmentObject var userData: UserData

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

Dengan pembantu ini yang membuatnya bekerja:

struct Observe<T: ObservableObject, V: View>: View {
    @ObservedObject var obj: T
    let content: (T) -> V
    var body: some View { content(obj) }
}
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.