중첩 된 ObservableObject에 바인딩하도록 SwiftUI보기에 지시하는 방법


18

라는 EnvironmentObject를 사용하는 SwiftUI보기가 appModel있습니다. 그런 다음 값을 판독하고 appModel.submodel.count그 안에 body방법. 속성이 업데이트 될 때 다시 렌더링 할 수 있도록 속성 count에 대한 내 견해를 바인딩 할 것으로 기대 submodel하지만 이런 일은 일어나지 않는 것 같습니다.

이것이 버그입니까? 그렇지 않은 경우 SwiftUI에서 뷰를 환경 객체의 중첩 속성에 바인딩하는 관용적 방법은 무엇입니까?

특히 내 모델은 다음과 같습니다.

class Submodel: ObservableObject {
  @Published var count = 0
}

class AppModel: ObservableObject {
  @Published var submodel: Submodel = Submodel()
}

내 견해는 다음과 같습니다.

struct ContentView: View {
  @EnvironmentObject var appModel: AppModel

  var body: some View {
    Text("Count: \(appModel.submodel.count)")
      .onTapGesture {
        self.appModel.submodel.count += 1
      }
  }
}

앱을 실행하고 레이블을 클릭하면 count속성이 증가하지만 레이블은 업데이트되지 않습니다.

appModel.submodel에 속성 으로 전달 하여이 문제를 해결할 수 ContentView있지만 가능하면 그렇게하지 않으려 고합니다.


또한 이와 같이 내 앱을 디자인하고 있습니다. 나는 보통 과거의 앱 개발에서 글로벌 App 객체를 가지고 있습니다. 다른 사람이 환경 변수로서 슈퍼 "앱"클래스의 디자인이 표준 관행이 될 것이라고 생각합니까? 또한 여러 EnvironmentObjects 사용을 고려하고 있었지만 유지 관리하기가 어렵습니다.
Michael Ozeryansky

답변:


22

중첩 된 모델은 SwiftUI에서 아직 작동하지 않지만 다음과 같은 작업을 수행 할 수 있습니다

class Submodel: ObservableObject {
    @Published var count = 0
}

class AppModel: ObservableObject {
    @Published var submodel: Submodel = Submodel()

    var anyCancellable: AnyCancellable? = nil

    init() {
        anyCancellable = submodel.objectWillChange.sink { (_) in
            self.objectWillChange.send()
        }
    } 
}

기본적으로 AppModel이벤트를 잡아서 SubmodelView로 더 보냅니다.

편집하다:

SubModel수업을 할 필요 가 없다면 다음과 같이 해보십시오.

struct Submodel{
    var count = 0
}

class AppModel: ObservableObject {
    @Published var submodel: Submodel = Submodel()
}

감사합니다. 도움이되었습니다. "SwiftUI에서 필요한 모델이 아직 작동하지 않습니다"라고 말하면 모델이 계획되어 있는지 알고 있습니까?
rjkaplan

확실하지는 않지만 제 의견으로는 효과가 있으며 프로젝트에서도 비슷한 것을 사용하므로 더 나은 접근 방식을 찾으면 편집 할 것입니다.
Sorin Lica

해야 @SorinLica SubmodelObservableObject 유형을?
Farhan Amjad

작동합니다! 멋진 해결책!
Md Shahed Hossain

1

세 가지 ViewModel 모두 통신 및 업데이트 가능

// First ViewModel
class FirstViewModel: ObservableObject {
var facadeViewModel: FacadeViewModels

facadeViewModel.firstViewModelUpdateSecondViewModel()
}

// Second ViewModel
class SecondViewModel: ObservableObject {

}

// FacadeViewModels Combine Both 

import Combine // so you can update thru nested Observable Objects

class FacadeViewModels: ObservableObject { 
lazy var firstViewModel: FirstViewModel = FirstViewModel(facadeViewModel: self)
  @Published var secondViewModel = secondViewModel()
}

var anyCancellable = Set<AnyCancellable>()

init() {
firstViewModel.objectWillChange.sink {
            self.objectWillChange.send()
        }.store(in: &anyCancellable)

secondViewModel.objectWillChange.sink {
            self.objectWillChange.send()
        }.store(in: &anyCancellable)
}

func firstViewModelUpdateSecondViewModel() {
     //Change something on secondViewModel
secondViewModel
}

Combine 솔루션에 대해 Sorin에게 감사합니다.


코드를 업데이트 할 수 있습니까? 많은 컴파일러 오류가 있습니다
DevB2F

-2

버그처럼 보입니다. xcode를 최신 버전으로 업데이트하면 중첩 된 ObservableObjects에 바인딩 할 때 올바르게 작동합니다.


현재 사용중인 xcode 버전을 확인할 수 있습니까? 현재 Xcode 11.0이 있으며이 문제가 발생합니다. 11.1로 업그레이드하는 데 문제가 있었지만 80 % 완료되지 않았습니다.
Michael Ozeryansky
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.