Swiftui - Làm cách nào để tôi khởi tạo một obsObject bằng cách sử dụng một môi trường như là một tham số?


9

Tôi không chắc đây có phải là một antipotype trong thế giới SwiftUI mới dũng cảm này mà chúng ta đang sống hay không, nhưng về cơ bản tôi có một @En môiObject với một số thông tin người dùng cơ bản được lưu trong đó mà quan điểm của tôi có thể gọi.

Tôi cũng có một @ObservedObject sở hữu một số dữ liệu cần thiết cho chế độ xem này.

Khi chế độ xem xuất hiện, tôi muốn sử dụng @En MôiObject đó để khởi tạo @ObservedObject:

struct MyCoolView: View { 

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

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

Thật không may, tôi không thể tự gọi biến môi trường cho đến khi khởi tạo:

"Không thể sử dụng thành viên 'userData' trong trình khởi tạo thuộc tính; trình khởi tạo thuộc tính chạy trước khi 'tự' có sẵn."

Tôi có thể thấy một vài tuyến đường có thể tiến về phía trước, nhưng tất cả đều cảm thấy như bị hack. Làm thế nào tôi nên tiếp cận điều này?


Có lẽ bạn có thể thử thêm một tùy chỉnh initvào struct.
nayem

Tôi đã thử điều đó và gặp một lỗi khá lạ: Property wrappers are not yet supported on local properties Về cơ bản, nó nói rằng tôi không thể tạo @ObservedObject trong một phương thức init.
snarik

Câu trả lời:


9

Đây là cách tiếp cận (IMO đơn giản nhất):

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

Đây là hoàn hảo. MyCoolView thực sự là một đứa trẻ đối với chế độ xem 'nhà' nơi tôi đã khai báo ObservedObject. Cảm ơn!
snarik

Nhưng nếu bạn muốn thao tác userData bên trong ViewObject mà không có ViewObject hoàn toàn mới được tạo ra mỗi lần thì sao?
BobiSad

0

thay vì tạo một khung nhìn phụ, bạn có thể thêm một trình khởi tạo giả để "ViewObject"bạn có thể gọi nó trước khi gọi trình khởi tạo thực

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

cho hồ sơ tôi đã không kiểm tra nó


0

Đây là một cách dễ dàng để làm điều đó:

struct MyCoolView: View {
    @EnvironmentObject var userData: UserData

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

Với người trợ giúp này làm cho nó hoạt động:

struct Observe<T: ObservableObject, V: View>: View {
    @ObservedObject var obj: T
    let content: (T) -> V
    var body: some View { content(obj) }
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.