1

I know there are a lot of questions out there with similar issues but almost all of them are reference/value issues. My case is a little different

I have a Viewcontroller that leverages UIHostingController and add's a SwiftUI view.

I have a viewmodel that's an ObservableObject and referenced in ViewController and then passed to SwiftUI View.

However if I update some values in ObservableObject it is not reflected to SwiftUI

What am I doing wrong here?

class DeveloperScreenViewController1: UIViewController {
let developerScreenViewModel: DeveloperScreenViewModel

private lazy var contentView: UIHostingController = {
    UIHostingController(rootView: DeveloperScreenView(developerScreenViewModel: developerScreenViewModel))
}()

init(viewModel: DeveloperScreenViewModel) {
    self.developerScreenViewModel = viewModel
    super.init(nibName: nil, bundle: Bundle.main)
}


override func viewDidLoad() {
    super.viewDidLoad()
     setupConstraints()

}

override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)
    self.developerScreenViewModel.setup()
}

private func setupConstraints() {
    // add swiftUI view as a subview
    addChild(self.contentView)
    self.contentView.view.translatesAutoresizingMaskIntoConstraints = false
    view.addSubview(self.contentView.view)
    
    // set constraints to match the parent viewcontroller's view
    NSLayoutConstraint.activate([
        view.leadingAnchor.constraint(equalTo: contentView.view.leadingAnchor),
        view.trailingAnchor.constraint(equalTo: contentView.view.trailingAnchor),
        view.topAnchor.constraint(equalTo: contentView.view.topAnchor),
        view.bottomAnchor.constraint(equalTo: contentView.view.bottomAnchor)
    ])
}

And then in ViewModel class

class DeveloperScreenViewModel: ObservableObject {

 @Published var environments: [Endpoint] = []
 @Published var realTimeUpdateToggle:Bool = false


public init() {
    // self.setup()
}

public func setup() {
    self.initializeListItems()
    self.initializeRealTimeToggle()
}

private func initializeListItems() {
    self.environments = EnvironmentStore.shared.changeableEndpoints
}

func initializeRealTimeToggle() {
   realTimeUpdateToggle = RealTimeUpdatesDeveloperUtils.isEnabled()
}

and SwiftUI is something like

struct DeveloperScreenView: View {

@ObservedObject var developerScreenViewModel: DeveloperScreenViewModel


var body: some View { 
            VStack {
                
                DeveloperScreenEnvironmentView(endPoints: developerScreenViewModel.environments)
                
                
                DeveloperScreenRealTimeUpdateToggleView(realTimeToggleItem: developerScreenViewModel.realTimeUpdateToggle)
                
            }            
}

When changes are made to this vars, lets say add a new element to array or set realTimeUpdateToggle to true, view in SwiftUI just dont get updated

@Published var environments: [Endpoint] = []
@Published var realTimeUpdateToggle:Bool = false
SpaceDust__
  • 4,844
  • 4
  • 43
  • 82
  • not sure if this is the problem but after `addSubview` you are missing the expected `contentView.didMove(toParent: self)`. Btw once you learn the child view controller pattern you should no longer need view model objects. – malhal Oct 19 '22 at 20:46

0 Answers0