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

라는 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있지만 가능하면 그렇게하지 않으려 고합니다.



답변

중첩 된 모델은 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()
}


답변

세 가지 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에게 감사합니다.


답변

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


답변