Trik untuk meningkatkan kinerja scrolling iPhone UITableView?

89

Saya memiliki tampilan yang sesuai yang memuat gambar yang cukup besar di setiap sel dan ketinggian sel bervariasi tergantung pada ukuran gambar. Performa pengguliran lumayan, tetapi terkadang bisa tersendat-sendat.

Saya menemukan tips ini yang saya temukan di blog FieryRobot:

glassy-scrolling-with-uitableview

more-glassy-scrolling-with-uitableview

Apakah ada yang punya tip untuk meningkatkan kinerja scrolling uitableview?

Yunus
sumber
Jika Anda perlu meng-cache ketinggian sel (yang bisa mahal untuk dihitung dan juga sering digunakan), saya telah memberikan contoh. Gunakan ini hanya jika sesuai dengan aplikasi Anda. stackoverflow.com/questions/1371223/…
Paul de Lange

Jawaban:

156
  1. Cache tinggi baris (tampilan tabel dapat sering meminta ini)
  2. Buat cache yang paling terakhir digunakan untuk gambar yang digunakan dalam tabel (dan batalkan semua entri tidak aktif saat Anda menerima peringatan memori)
  3. Menarik segala sesuatu di UITableViewCell's drawRect:jika mungkin subviews menghindari di semua biaya (atau jika Anda membutuhkan fungsi aksesibilitas standar, tampilan konten ini drawRect:)
  4. Jadikan UITableViewCelllapisan Anda buram (hal yang sama berlaku untuk tampilan konten jika Anda memilikinya)
  5. Gunakan fungsionalitas reusableCellIdentifier seperti yang direkomendasikan oleh UITableViewcontoh / dokumentasi
  6. Hindari gradien / efek grafis rumit yang tidak dimasukkan sebelumnya ke dalam UIImages
rpetrich.dll
sumber
5
Selain itu, gambar yang diunduh harus diperkecil ke ukuran imageView sebelum ditampilkan di sel!
Zoltán Matók
4
Saya ingin menambahkan pada jawaban ini satu pengalaman saya dari beberapa tahun terakhir - memiliki sel transparan mungkin tidak pernah menjadi penyebab kinerja pengguliran yang buruk. Kami memiliki aplikasi dengan sel yang SANGAT rumit (20+ subview) dan semuanya transparan untuk menampilkan latar belakang. Dengan pengoptimalan yang tepat, transparansi tidak membuat perbedaan bahkan pada 3GS. Sebenarnya hal yang paling memperlambat barang adalah pemuatan ujung pena sebelum ada cukup sel untuk membatalkan antrean dari tampilan tabel. Jika menggunakan subview, pastikan untuk memiliki hierarki yang efisien dan Anda tidak perlu menggunakan drawRect.
Accatyyc
@Accatyyc, sepertinya saya memiliki masalah yang sama. Ada sedikit jeda ketika tidak ada cukup sel untuk melakukan dequeue, ketika 3-4 sel di-dequeue maka pengguliran berjalan lancar. Apakah ada cara untuk melakukan pramuat sel sehingga ada sel yang perlu didequeue dan tidak memuat file NIB saat menggulir?
Tiois
@Tiois Tentu ada. Anda perlu menggunakan cara lama untuk menghapus sel (jangan mendaftarkan class / nibs, tetapi buatlah jika dequeueCellWithIdentifier: mengembalikan nil). Dengan cara ini Anda bisa membuat sekumpulan sel bahkan sebelum tampilan tabel Anda ada, misalnya membuat 20 sel sebelumnya. Lalu, alih-alih membuat yang baru di cellForRowAtIndexPath :, Anda menariknya dari cache Anda sendiri terlebih dahulu, hingga kosong.
Accatyyc
Saya menggunakan UICollectionView dan menghadapi masalah yang sama. Di file ujung pena sel kustom saya. Saya menggunakan beberapa subview termasuk UIwebView dan UIImageView di dalam UIstackView vertikal. ketika saya menggulir daftar saya digunakan kembali sel membutuhkan waktu yang signifikan untuk menyesuaikan ukurannya dan pengguliran terlihat sangat tersendat.
Mansuu ....
40
  1. Jika Anda membuat subclass UITableViewCell, jangan gunakan Nib, tulislah dalam kode sebagai gantinya. Ini jauh lebih cepat daripada memuat file Nib.
  2. Jika Anda menggunakan gambar, pastikan Anda menyimpannya dalam cache sehingga Anda tidak perlu memuat dari file lebih dari satu kali untuk masing-masing (jika Anda memiliki memori - Anda akan terkejut betapa banyak ruang yang digunakan gambar).
  3. Buat elemen menjadi buram sebanyak mungkin. Demikian pula, cobalah untuk tidak menggunakan gambar dengan transparansi.
Shaggy Frog
sumber
3
jangan khawatir ... itu troll. jawaban yang bagus!
Steav
79
Suara yang turun mungkin karena "hindari nibs" adalah nasihat yang buruk untuk meningkatkan kinerja. Jika Anda menggunakan kembali sel, sel tidak direkonstruksi dari ujung sama sekali saat menggulir.
Steven Fisher
6
Biji memiliki kecepatan yang setara, atau sedikit lebih cepat berdasarkan penelitian Cocoa with Love. cocoawithlove.com/2010/03/…
MaxGabriel
@Steven Fisher menggunakan Nib mungkin lebih lambat ketika tabel allocs dan sel deallocs, misalnya - selama pengguliran cepat.
Sound Blaster
3
Penggunaan NIB mungkin lebih lambat saat sel sedang dibangun . Jika Anda menggunakan daur ulang sel, hanya ada cukup sel yang dialokasikan untuk mengisi layar; katakanlah, mungkin paling banyak 10. Saat Anda menggulir, sel tidak dibuat. Mereka hanya digunakan kembali , tidak dialokasikan dan dialokasikan kembali. Dan, tentu saja, tidak ada biaya untuk melakukan dealloc. Jadi tidak, ini tidak benar.
Steven Fisher
34

Pengembang di balik Tweetie telah menulis secara ekstensif tentang ini dan memiliki beberapa kode yang menunjukkan bagaimana hal itu dilakukan untuk aplikasi itu. Pada dasarnya, dia menganjurkan satu tampilan kustom per sel tabel, dan menggambarnya secara manual (daripada melakukan subview dengan Interface Builder, di antara opsi lainnya).

fast-scrolling-in-tweetie-with-uitableview

Selain itu, Apple telah memperbarui kode sampelnya sendiri untuk TableView dalam tutorial TableViewSuite-nya (mungkin menanggapi ini?)

TableViewSuite

beno
sumber
1
Ini adalah solusi yang luar biasa. Saya hanya ingin tahu bagaimana cara menambahkan UIButton ke dalam cellView? Apakah itu digambar dengan metode drawRect?
Sukitha Udugamasooriya
1
@beno, tautan Anda sepertinya rusak (yang pertama), ada kesempatan untuk mencoba artikel aslinya?
apouche
3
Artikel asli dapat dibaca di sini: web.archive.org/web/20100922230053/http://blog.atebits.com/2008/…
jverdi
menambahkan tautan ke arsip web karena versi asli tidak ada
Ralph Willgoss
1

Pembunuh kinerja # 1 untuk pengguliran UITableView menggambar bayangan pada setiap lapisan tampilan sel, jadi jika kinerja pengguliran penting maka jangan lakukan bayangan kecuali pada dasarnya itu tidak memperlambat utas utama Anda.

Saya pikir ini harus dikatakan karena tidak ada jawaban yang diterima menyebutkan bayangan dan lapisan. : +)

JackyJohnson
sumber
6
jika masalahnya adalah bayangan, tambahkan dua baris kode ini dan semuanya bekerja dengan sempurna self.layer.shouldRasterize = YES; self.layer.rasterizationScale = UIScreen.mainScreen.scale;
Pedro Romão
0

Masalah apa pun dengan UITableViewkinerja pengguliran dapat diselesaikan dengan menggunakan teknik yang telah dijelaskan dalam jawaban lain. Namun seringkali kinerja yang lamban disebabkan oleh sesuatu yang secara inheren keliru, atau berulang.

Fakta yang UITableViewmenggunakan kembali sel, dan fakta bahwa setiap sel mungkin membutuhkan gambarnya sendiri - bersama-sama membuat solusinya agak rumit. Dari cara pemecahannya secara umum, berikut saya rangkum hal-hal yang harus diperhatikan:

  1. Memuat data ke dalam sumber data - dari REST / database. Langkah ini harus dilakukan di latar belakang, akhirnya menggunakan dispatch_async bersama dengan antrian GCD.
  2. Membuat dan menginisialisasi objek model data yang relevan dan meletakkannya di dalam array
  3. [tableView reloaddata]
  4. Di dalamnya cellForRowAtIndexPath, masukkan kode yang akan mengatur data (teks) dari objek model data yang benar dari array.
  5. Sekarang gambar mungkin dalam bentuk URL juga, jadi langkah ini mungkin sedikit aneh karena penggunaan ulang sel dilakukan oleh tampilan tabel. Inti dari fakta ini adalah memuat sekali lagi gambar dari cache perangkat / URL menggunakan antrian async, lalu mengaturnya ke cell.image yang benar (apa pun properti gambar sel Anda).

Untuk menghindari masalah, lihat tutorial ini tentang pemuatan lambat gambar di dalam tampilan tabel.

Nirav Bhatt
sumber