如何告诉SwiftUI视图绑定到嵌套的ObservableObjects


18

我有一个SwiftUI视图,其中包含一个名为的EnvironmentObject 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对象。还有人认为超级“ App”类作为环境变量的这种设计将成为标准做法吗?我也在考虑使用多个EnvironmentObject,但这很难维护。
Michael Ozeryansky '19

Answers:


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捕获事件Submodel并将其发送到视图

编辑:

如果您不需要SubModel上课,则可以尝试以下方法:

struct Submodel{
    var count = 0
}

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

谢谢,这是有帮助的!当您说“嵌套模型在SwiftUI中尚不可用”时,您确定要确定它们是已计划的吗?
rjkaplan

我不确定,但是我认为它应该起作用,我在项目中也使用了类似的方法,因此,如果我找到更好的方法,我将进行编辑
Sorin Lica

@SorinLica应该SubmodelObservableObject 类型?
法罕·阿姆贾德

工作正常!很棒的解决方案!
沙赫德·侯赛因

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
}

感谢Sorin提供的Combine解决方案。


您可以更新代码吗?它有很多编译器错误
DevB2F

-2

它看起来像错误。当我将xcode更新到最新版本时,绑定到嵌套的ObservableObjects时它可以正常工作


您能说明一下您当前使用的xcode版本吗?我目前有Xcode 11.0并遇到此问题。我在升级到11.1时遇到了麻烦,无法完成80%的升级。
Michael Ozeryansky '19
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.