Обработка потока данных в iOS 17 и использование наблюдаемых переменных внутри TextField
Я пытаюсь перейти на iOS 17, используя@Observable
.
У меня есть глобальная модель представления приложения, в которой я вызываю модель экзамена со всеми необходимыми мне значениями внутри.
Согласно рекомендациям Apple , я использую свою модель представления следующим образом.
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)
}
}
}
Затем я использую свою модель в InfoView следующим образом.
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)
}
}
}
Как вы можете видеть в первом текстовом поле, которое я использую$model.exam.title
но, похоже, это не работает, потому что выдает мне эту ошибку
Невозможно найти $model в области видимости.
Поэтому я попробовал с@Bindable
но значение, которое пользователь вставляет в textField, не читается и всегда возвращает пустую строку, где я ошибаюсь? Кто-нибудь начал работать на iOS 17?
3 ответа
Следующий пример кода с@Bindable
у меня работает на iOS17. Когда$model.exam.title
изменяется вTextField
, пользовательский интерфейс обновляется и отображает измененное значение.
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()
}
Если вы используете@Environment
вам нужно преобразовать, например, в
@Bindable var exam = model.exam
TitledField(text: $exam.title, isMandatory: true, descriptionLabel: "", placeholder: "")
@Bindable
это неDynamicProperty
так что его можно использовать внутриbody
как и любая другая структура.
Хорошей отправной точкой является:
Я также добавил пример проекта с помощью «добавить»: