Я пытался создать уменьшенное многоразовое представление для простого проекта SwiftUI. Однако я получаю неожиданные результаты и пытаюсь понять, почему.
Вот мой надуманный пример, чтобы выделить проблему
Используя этот пример, как создать повторно используемую RowView вместо HStack
в списке
var body: some View {
List(vm.gradings) { item in
// how should you refactor out this ??
HStack {
Text(item.grade)
Text(item.pass ? "Pass" : "Fail")
}
}
}
Я использую Firebase для запуска изменения модели. т.е. изменение оценки для прохождения или неудачи и ожидание того, что в подробном представлении списка будет отображено это изменение.
Вышеуказанный метод работает, как ожидалось, в то время как в представлении списка и строка изменяется при изменении данных.
Однако, когда я пытаюсь изменить вид, только один работает, как и ожидалось. В идеале я хотел бы передать объект Grading
, но это не приводит к обновлению представления.
Попытка различных подпредставлений и их результатов
var body: some View {
List(vm.gradings) { item in
// Works
RowA(grade: item.grade, pass: item.pass)
// Fails
// RowB(item: item)
// Fails
// RowC(item: item)
// Default - works as expected
// HStack {
// Text(item.grade)
// Text(item.pass ? "Pass" : "Fail")
// }
}
}
Вот3 варианта строки
// Works
struct RowA: View {
var grade: String
var pass: Bool
var body: some View {
HStack {
Text(grade)
Text(pass ? "Pass" : "Fail")
}
}
}
// Fails
struct RowB: View {
var item: Grading
var body: some View {
HStack {
Text(item.grade)
Text(item.pass ? "Pass" : "Fail")
}
}
}
// Fails
struct RowC: View {
@State var item: Grading
var body: some View {
HStack {
Text(item.grade)
Text(item.pass ? "Pass" : "Fail")
}
}
}
Работа вокруг
// Allows me to pass in just the model
struct RowD: View {
private var item = Grading()
private var grade: String = ""
private var pass: Bool = false
init(item: Grading) {
self.item = item
self.grade = item.grade
self.pass = item.pass
}
var body: some View {
HStack {
Text(grade)
Text(pass ? "Pass" : "Fail")
}
}
}
Моя модель просмотра
class StudentGradingsUIViewModel: ObservableObject {
@Published var detailedstudent: DetailedStudent
var gradings: [Grading] {
detailedstudent.student.gradings
}
init(student: DetailedStudent) {
self.detailedstudent = student
}
}