//: [Previous](@previous)
import SwiftUI
import PlaygroundSupport
// class observer and update with a button.
public class ItemClass2 {
public var name: String
let id: UUID
public var number: Int = 0
public init(name: String) {
self.name = name
self.id = .init()
}
}
class ContentViewModel: ObservableObject {
@Published var item = ItemClass2(name: "first")
}
struct ContentView: View {
@StateObject var viewModel = ContentViewModel()
var body: some View {
VStack {
Text("Item Struct")
.font(.title)
Text("Name: \(viewModel.item.name)")
.font(.headline)
Text("Number: \(viewModel.item.number)")
TextField("name", text: $viewModel.item.name)
.textFieldStyle(.roundedBorder)
Button {
viewModel.item.number += 1
// viewModel
// .objectWillChange
// .send()
} label: {
Text("increase number")
}
}
.frame(width: 400, height: 600)
}
}
PlaygroundPage.current.setLiveView(ContentView())
If you put this in a playground, and tap the increment button, you'll notice that the number doesn't increment until the text field is modified.
I want to bind viewModel.item.number to the Button. If I change the property wrapper for the @StateObject var viewModel = ContentViewModel() to @Bindable it isn't allowed because viewModel is a class.
If we uncomment the objectWillChange lines, it solves the problem, but it feels sketchy and counter to the purpose of SwiftUI MVVM to have to manually call send().
How can I update the viewModel from a button tap, in a way that adheres to MVVM?