'Noob Swift UI question - Updating views from model class
I have my ItemModel and my Contentview, but when run the program the view doesn't update with the new quantity in real time. How do I get the model and the view to "talk"
import Foundation
import SwiftUI
class Item: ObservableObject {
var name: String
@Published var qty: Int
init(name: String, qty: Int) {
self.name = name
self.qty = qty
}
}
var metzScissor = Item(name: "Metz Scissor", qty: 5)
import SwiftUI
struct ContentView: View {
var body: some View {
NavigationView {
VStack {
Text("Items In Stock")
.font(.title)
.padding()
Spacer()
NavigationLink (
destination: ItemDetailView(),
label: {
Text(metzScissor.name)
})
Spacer()
}
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
Do I need to make an instance of my model class within the view file?
Solution 1:[1]
Normally the ObservableObject that holds your model structs in @Published properties is a singleton that you pass into the View struct hierarchy using the environmentObject modifier in the body of the App struct. This makes it available in ContentView and every View below and body will run when the model structs change if you declare an @EnvironmentObject var.
The reason it’s a singleton is that you can have a different singleton containing sample data to use when previewing. The reason we don’t use @StateObject is that is not init during previewing and you usually don’t need the App struct body to be recomputed when the model struct changes.
Perhaps something like this:
import SwiftUI
struct Item: Identifiable {
let id = UUID()
var name: String
var qty: Int
init(name: String, qty: Int) {
self.name = name
self.qty = qty
}
}
class Model: ObservableObject {
@Published items: [Item] = []
static let shared = Model()
static let preview: Model = {
let metzScissor = Item(name: "Metz Scissor", qty: 5)
return Model(items:[metzScissor])
}()
}
import SwiftUI
@main
struct TestApp: App {
var body: some Scene {
WindowGroup {
ContentView()
.environmentObject(Model.shared)
}
}
}
import SwiftUI
struct ContentView: View {
@EnvironmentObject var model: Model
var body: some View {
NavigationView {
List{
ForEach(model.items) item in
NavigationLink (
destination: ItemView(item: item),
label: {
Text(item.name)
})
}
.navigationTitle("Items in Stock")
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
.environmentObject(Model.preview)
}
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 |
