Dlaczego @Published aktualizuje tekst, ale nie aktualizuje listy?
Nie rozumiem, dlaczego Text
aktualizacje, ale List
nie.
Mam model z @Published
tablicą dat. Istnieje również metoda generowania tekstu na podstawie dat.
Oto uproszczona wersja:
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")
}
}
I pokazuję ten tekst moim zdaniem. Oto uproszczona wersja:
struct DataView: View {
@ObservedObject var model: DataModel
var body: some View {
ScrollView {
Text(model.summary())
}
}
}
Działa: kiedy użytkownik z poziomu interfejsu użytkownika w Widoku doda datę do model.selectedDates
, tekst podsumowania jest odpowiednio zaktualizowany.
Teraz chcę zastąpić tekst listą wierszy.
Zmieniam metodę:
func summary() -> [String] {
var lines: [String] = []
for date in selectedDates.sorted().reversed() {
let l = "\(someOtherStuff) \(date.dateFormatted)"
lines.append(l)
}
return lines
}
I zmień widok:
var body: some View {
ScrollView {
List {
ForEach(model.summary(), id: \.self) { line in
Text(line)
}
}
}
}
Ale to nie działa: w ogóle nie ma tekstu na liście, nigdy nie jest aktualizowany, gdy użytkownik dodaje datę do model.selectedDates
.
Co ja robię źle?
Odpowiedzi
Udało mi się znaleźć tę odpowiedź na poprzedni post w SO, który może być rozwiązaniem twojego problemu. Kiedy mówisz, że na liście nie ma żadnego tekstu, czy debugowałeś, aby to sprawdzić, czy po prostu nie było żadnych danych na ekranie?
Kiedy zrobiłem kopię twojego fragmentu kodu i majstrowałem przy nim, okazało się, że w rzeczywistości na liście były dane, które Lista próbowała wyświetlić na ekranie, ale ramka listy była zastępowana przez widok przewijania. Zagnieżdżenie wszystkiego w GeometryReader i nadanie listy rozmiaru ramki nadało programowi funkcjonalność, której szukasz.
Użyj ScrollView lub listy dla swoich danych. Jeśli lista ma wiele wartości, automatycznie zmienia się w listę przewijalną. Więc uważam, że możesz po prostu całkowicie usunąć ScrollView.
Oto naprawiony wariant (z kilkoma replikacjami - musisz więc dostosować go z powrotem do swojego projektu).
Przetestowano z 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)
}
}
}
}
}