简体   繁体   中英

How to tell SwiftUI views to bind to more than one nested ObservableObject

I have two classes nested in another class, which is an observable object in a SwiftUI view. Even though properties in the nested classes are declared as @Published, their values (when they change) do not update in the main view.

A similar question has been asked here, and I could use it to get it to work for one of the two subclasses, but not both.

How to tell SwiftUI views to bind to nested ObservableObjects

This is the model:

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

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

class Model: ObservableObject {
  @Published var submodel1: Submodel1 = Submodel1()
  @Published var submodel2: Submodel2 = Submodel2()
}

And this is the main view:

struct ContentView: View {
  @ObservedObject var model: Model = Model()

  var body: some View {
    VStack {
      Text("Count: \(model.submodel1.count)")
        .onTapGesture {
          self.model.submodel1.count += 1
        }
      Text("Count: \(model.submodel2.count)")
        .onTapGesture {
          self.model.submodel2.count += 1
        }
    }
  }
}

Adding this to the model class (see previous Stackoverflow question) works for updating on submodel1 changes, but not both:

  var anyCancellable: AnyCancellable? = nil
  init() {
      anyCancellable = submodel1.objectWillChange.sink { (_) in
          self.objectWillChange.send()
      }
   }

What I'm looking for is some way to pass on changes of both the submodel1 and submodel2 to my view.

You can expand upon the answer in the question you linked to by using CombineLatest to have your model fire its objectWillChange publisher when either of the underlying objects change:

import Combine

class Model: ObservableObject {
    @Published var submodel1: Submodel1 = Submodel1()
    @Published var submodel2: Submodel2 = Submodel2()

    var anyCancellable: AnyCancellable? = nil

    init() {
        anyCancellable = Publishers.CombineLatest(submodel1.$count,submodel2.$count).sink(receiveValue: {_ in
            self.objectWillChange.send()
        })
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM