Mengapa @Published memperbarui Teks tetapi tidak memperbarui Daftar?

Dec 15 2020

Saya tidak mengerti mengapa Textpembaruan tetapi Listtidak.

Saya memiliki model dengan @Publishedarray tanggal. Ada juga metode untuk menghasilkan teks dari tanggal.

Berikut versi yang disederhanakan:

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")
    }

}

Dan saya tunjukkan teks ini dalam pandangan saya. Berikut versi yang disederhanakan:

struct DataView: View {

    @ObservedObject var model: DataModel

    var body: some View {
        ScrollView {
            Text(model.summary())
        }
    }

}

Berfungsi: ketika pengguna, dari UI di View, menambahkan tanggal ke model.selectedDates, teks ringkasan udpated dengan benar.


Sekarang saya ingin mengganti teks dengan Daftar baris.

Saya mengubah metode:

    func summary() -> [String] {
        var lines: [String] = []
        for date in selectedDates.sorted().reversed() {
            let l = "\(someOtherStuff) \(date.dateFormatted)"
            lines.append(l)
        }
        return lines
    }

Dan ubah tampilan:

    var body: some View {
        ScrollView {
            List {
                ForEach(model.summary(), id: \.self) { line in
                    Text(line)
                }
            }
        }
    }

Tapi ini tidak berhasil: tidak ada teks sama sekali dalam daftar, tidak pernah diperbarui saat pengguna menambahkan tanggal ke model.selectedDates.

Apa yang saya lakukan salah?

Jawaban

2 Nate Dec 15 2020 at 08:34

Saya dapat menemukan jawaban ini untuk posting sebelumnya di SO yang mungkin menjadi solusi untuk masalah Anda. Ketika Anda mengatakan bahwa tidak ada teks sama sekali dalam daftar, apakah Anda melakukan debug untuk memverifikasi itu, atau apakah tidak ada data yang ditampilkan di layar?

Ketika saya membuat salinan cuplikan kode Anda dan mengotak-atiknya, ternyata sebenarnya ada data dalam daftar yang coba ditampilkan Daftar di layar, tetapi bingkai Daftar itu diganti oleh Scrollview. Menyusun semua yang ada di dalam GeometryReader dan memberikan ukuran bingkai ke Daftar memberi program fungsionalitas yang terdengar seperti yang Anda cari.

1 nicksarno Dec 15 2020 at 10:22

Gunakan ScrollView atau List untuk data Anda. Jika Daftar memiliki beberapa nilai, secara otomatis berubah menjadi Daftar yang dapat digulir. Jadi, saya yakin Anda bisa menghapus ScrollView sepenuhnya.

1 Asperi Dec 15 2020 at 10:53

Berikut adalah varian tetap yang berhasil (dengan beberapa replikasi - jadi Anda perlu menyesuaikannya kembali ke proyek Anda).

Diuji dengan 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)
                }
            }
        }
    }
    
}