I'm trying to migrate to iOS 17 using @Observable
.
I have a global view model of the app where I call an Exam model with all the values I need inside.
According to Apple guidelines I'm using my view model like this
import Foundation
import Observation
struct Exam: {
var title: String = ""
}
@Observable
final class Global {
var exam = Exam()
}
import SwiftUI
@main
struct TestApp: App {
@State private var model = Global()
var body: some Scene {
WindowGroup {
InfoView()
.environment(model)
}
}
}
Next I use my model within the InfoView like this
struct InfoView: View {
// @Bindable private var model = Global()
@Environment(Global.self) private var model
var body: some View {
VStack {
TitledField(text: $model.exam.title, isMandatory: true, descriptionLabel: "", placeholder: "")
.submitLabel(.continue)
}
}
}
As you can see in the first custom textField I use $model.exam.title
but it doesn't seem to work because it gives me this error
Cannot find '$model' in scope
So I tried with @Bindable
but the value that the user inserts in the textField is not read and always returns an empty string where am I going wrong? Has anyone started working on iOS 17?
The following example code with @Bindable
works for me on iOS17.
When the $model.exam.title
is changed in the TextField
,
the UI is refreshed and displays the changed value.
import SwiftUI
import Observation
@main
struct TestApp: App {
@State private var model = Global()
var body: some Scene {
WindowGroup {
InfoView(model: model) // <-- here
}
}
}
struct InfoView: View {
@Bindable var model: Global // <-- here
var body: some View {
VStack {
TextField("", text: $model.exam.title).border(.red)
.submitLabel(.continue)
Text(model.exam.title) // <-- for testing
}
}
}
struct Exam {
var title: String = "exam-title"
}
@Observable
final class Global {
var exam = Exam()
}