Я использую SwiftData с представлением, предназначенным для обновления @Model.
Вот мои данные:
@Model
final class Pet {
var name: String
var gender: Gender
var type: String
var race: String
var birthdate: Date
var color: String
var eyeColor: String
var photo: Data?
var identification: Identification?
init(
name: String,
gender: Gender,
type: String,
race: String,
birthdate: Date,
color: String,
eyeColor: String,
photo: Data?
) {
self.name = name
self.gender = gender
self.type = type
self.race = race
self.birthdate = birthdate
self.color = color
self.eyeColor = eyeColor
self.photo = photo
}
}
@Model
final class Identification {
var chip: Int?
var chipLocation: String?
var tatoo: String?
var tatooLocation: String?
init(chip: Int?, chipLocation: String?, tatoo: String?, tatooLocation: String?) {
self.chip = chip
self.chipLocation = chipLocation
self.tatoo = tatoo
self.tatooLocation = tatooLocation
}
}
Как видите, у меня есть тип под названием «Идентификация», вложенный в модель «Питомец», и он не является обязательным.
Более того, все его свойства также являются необязательными.
Я пытаюсь отредактировать свойство чипа следующим образом:
struct EditInformationView: View {
@Environment(Pet.self) var pet
var body: some View {
@Bindable var pet = pet
Form {
Section("Identification") {
TextField("Chip", value: $pet.identification?.chip)
}
}
}
}
Мой вопрос очень прост: как мне отредактировать параметр чипа с помощью TextField?
Я немного потерялся и был бы признателен за небольшую помощь, большое спасибо :)
Я попытался использовать необязательную цепочку, как предложил мне Xcode, но это не сработало.
Вы можете попробовать этот простой подход, используя
промежуточная переменная и .onSubmit
,
как показано в примере кода:
struct EditInformationView: View {
@Environment(Pet.self) var pet
@State private var chipVal = 0 // <--- here
var body: some View {
@Bindable var pet = pet
Form {
Section("Identification") {
TextField("Chip", value: $chipVal, format: .number) // <--- here
.onSubmit {
pet.identification?.chip = chipVal // <--- here
}
}
}
.onAppear {
if let chipv = pet.identification?.chip { // <--- here
chipVal = chipv
}
}
}
}
Обратите внимание, вы также можете использовать .onChange(of: chipVal)
Вы можете использовать любое из «Дополнительных решений привязки».
Вариант 1
struct EditInformationView: View {
@Environment(Pet.self) var pet
var body: some View {
@Bindable var pet = pet
Form {
Section("Identification") {
if let identification = Binding($pet.identification) {
TextField("Chip", value: identification.chip, format: .number)
} else {
ProgressView()
.task {
pet.identification = Identification(chip: nil, chipLocation: nil, tatoo: nil, tatooLocation: nil)
}
}
}
}
}
}
Вариант 2
struct EditInformationView: View {
@Environment(Pet.self) var pet
var body: some View {
@Bindable var pet = pet
Form {
Section("Identification") {
TextField("Chip", value: ($pet.identification ?? Identification(chip: nil, chipLocation: nil, tatoo: nil, tatooLocation: nil)).chip, format: .number)
}
}
}
}
@MainActor func ?? <Element> (lhs: Binding<Element?>, rhs: Element) -> Binding<Element> {
Binding {
lhs.wrappedValue ?? rhs
} set: { newValue in
lhs.wrappedValue = newValue
}
}
Если вы ищете ТАК, есть еще несколько.
Суть в том, чтобы разобраться с идентификацией до того, как заняться ее свойствами. Есть бесконечное количество способов справиться с этим.