Почему @Published обновляет текст, но не обновляет список?
Я не понимаю, почему Text
обновления, но List
нет.
У меня есть модель с @Published
массивом дат. Также есть способ генерировать текст из дат.
Вот упрощенная версия:
class DataModel: NSObject, ObservableObject {
@Published var selectedDates: [Date] = []
func summary() -> String {
var lines: [String] = []
for date in selectedDates.sorted().reversed() {
let l = "\(someOtherStuff) \(date.dateFormatted)"
lines.append(l)
}
return lines.joined(separator: "\n")
}
}
И я показываю этот текст с моей точки зрения. Вот упрощенная версия:
struct DataView: View {
@ObservedObject var model: DataModel
var body: some View {
ScrollView {
Text(model.summary())
}
}
}
Это работает: когда пользователь из пользовательского интерфейса в представлении добавляет дату model.selectedDates
, текст сводки правильно обновляется.
Теперь я хочу заменить текст списком строк.
Меняю способ:
func summary() -> [String] {
var lines: [String] = []
for date in selectedDates.sorted().reversed() {
let l = "\(someOtherStuff) \(date.dateFormatted)"
lines.append(l)
}
return lines
}
И изменим вид:
var body: some View {
ScrollView {
List {
ForEach(model.summary(), id: \.self) { line in
Text(line)
}
}
}
}
Но это не работает: в списке вообще нет текста, он никогда не обновляется, когда пользователь добавляет дату в model.selectedDates
.
Что я делаю неправильно?
Ответы
Мне удалось найти этот ответ на предыдущий пост на SO, который может быть решением вашей проблемы. Когда вы говорите, что в списке вообще нет текста, вы выполняли отладку, чтобы убедиться в этом, или на экране просто не отображались данные?
Когда я сделал копию вашего фрагмента кода и возился с ним, оказалось, что в списке действительно были данные, которые List пытался отобразить на экране, но фрейм List перекрывался Scrollview. Вложение всего в GeometryReader и указание размера кадра в List дало программе функциональность, которая звучит так, как будто вы ищете.
Либо используйте ScrollView, либо список для ваших данных. Если список имеет несколько значений, он автоматически превращается в список с возможностью прокрутки. Итак, я считаю, что вы можете полностью удалить ScrollView.
Вот фиксированный рабочий вариант (с некоторыми репликациями - так что вам нужно адаптировать его обратно к вашему проекту).
Протестировано с Xcode 12.1 / iOS 14.1
class DataModel: NSObject, ObservableObject {
@Published var selectedDates: [Date] = []
func summary() -> [String] {
var lines: [String] = []
for date in selectedDates.sorted().reversed() {
let l = "someOtherStuff \(date)"
lines.append(l)
}
return lines
}
}
struct DataView: View {
@ObservedObject var model: DateDataModel = DataModel()
var body: some View {
VStack {
Button("Add") { model.selectedDates.append(Date())}
List {
ForEach(model.summary(), id: \.self) { line in
Text(line)
}
}
}
}
}