Swiftui-environmentobject를 매개 변수로 사용하여 observeObject를 어떻게 초기화합니까?


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.