Bagaimana cara menghindari uicollectionview membatalkan pilihan semua item ketika snapshot baru diterapkan?

Saat saya memanggil dataSource?.apply(snapshot, animatingDifferences: true), UICollectionView terkait membatalkan pilihan semua sel.

Ini adalah masalah ketika menerima data baru di latar belakang karena, ketika perubahan ini diterapkan, pengguna melihat pilihannya saat ini hilang.

Bagaimana cara menghindari pembatalan pilihan semua item koleksi ketika apply(snapshot: animatingDifferences) dipanggil?


person AirXygène    schedule 04.05.2021    source sumber
comment
Tentunya banyak hal bergantung pada apa yang Anda lakukan untuk menunjukkan pilihan kepada pengguna.   -  person matt    schedule 04.05.2021
comment
@matt - latar belakang sel digambar dengan warna berbeda. Sebenarnya saya menggunakan UIBackgroundConfiguration, tapi menurut saya itu tidak relevan. Sebelum menerapkan(snapshot:) pilihan UICollectionView tidak kosong, setelah panggilan, kosong.   -  person AirXygène    schedule 04.05.2021
comment
Tentu saja itu relevan. Hal yang perlu Anda pikirkan di sini adalah bahwa gagasan pemilihan didasarkan pada data dengan benar, bukan berdasarkan baris. Anda entah bagaimana telah menyiapkan kode yang mewarnai latar belakang. Kode tersebut perlu mengetahui apakah data ini merupakan data yang dipilih.   -  person matt    schedule 04.05.2021
comment
Saya meluangkan waktu untuk memikirkannya, tetapi saya rasa saya akan tetap berpendapat berbeda. Informasi seleksi tidak boleh menjadi bagian dari model. Saya dapat menerima bahwa ini berada di antara model dan tampilan, tetapi hal itu menimbulkan masalah dalam menjaga informasi tersebut tetap sinkron dengan daftar jalur indeks yang dipilih yang disimpan di dalam tampilan koleksi. Saya menemukan akar penyebab masalahnya (lihat jawaban), dan itu tidak ada hubungannya. Bagaimanapun, saya berterima kasih atas upaya Anda membantu. Salam.   -  person AirXygène    schedule 10.05.2021


Jawaban (1)


Setelah menggali beberapa kali, saya menemukan akar masalahnya, dan itu terletak di dalam kode Apple. Minimal, saya akan menyebutnya sebagai fitur yang tidak terdokumentasi, beberapa orang mungkin mengatakan itu adalah bug.

Ketika snapshot diterapkan, perilaku UICollectionViewDiffableDataSource berbeda, apakah ItemIdentifierType adalah tipe nilai atau tipe referensi.

Tentu saja, ItemIdentifierType Anda harus sesuai dengan Hashable, tetapi saat menelepon apply(snapshot, animatingDifferences: true):

  • Jika ItemIdentifierType adalah tipe nilai (struct), maka fungsi ==dan hash dipanggil, untuk membandingkan item dari snapshot yang baru diterima dengan item dari snapshot yang saat ini ditampilkan, yang memungkinkan untuk menemukan perbedaan, menganimasikan perbedaan, dan pertahankan pilihan jika ada (yang merupakan masalah awal yang saya minta bantuannya).
  • Jika ItemIdentifierType adalah tipe referensi (kelas), maka fungsi ==dan hash tidak dipanggil, yang berarti bahwa item dari snapshot baru dan snapshot yang ditampilkan saat ini dibandingkan dengan persamaan referensi kosong (adalah pointer sama). Akibatnya, jika Anda membuat item dari awal dengan instance baru yang memiliki hash yang sama, maka perbandingannya selalu salah, dan Anda tidak mendapatkan animasinya, dan Anda kehilangan pilihan.

Salah satu solusi mudah dalam situasi ini adalah dengan merangkum tipe referensi Anda ke dalam sebuah struct, yang akan meneruskan == dan hash ke kelas, dan menggunakan struct ini sebagai ItemIdentifierType

person AirXygène    schedule 10.05.2021