İPhone UITableView kaydırma performansını iyileştirmek için püf noktaları?


89

Her hücreye oldukça büyük görüntüler yükleyen kullanışlı bir görüşüm var ve hücre yükseklikleri görüntünün boyutuna bağlı olarak değişiyor. Kaydırma performansı iyi, ancak bazen sarsıntılı olabilir.

FieryRobot blogunda bulduğum şu ipuçlarını buldum:

uitableview ile camsı kaydırma

uitableview ile daha camsı kaydırma

Uitableview kaydırma performansını iyileştirmek için herhangi bir ipucu olan var mı?


Hücre yüksekliklerini önbelleğe almanız gerekiyorsa (hesaplaması pahalı olabilir ve sıklıkla kullanılır), bir örnek verdim. Bunu yalnızca uygulamanıza uygunsa kullanın. stackoverflow.com/questions/1371223/…
Paul de Lange

Yanıtlar:


156
  1. Satırların yüksekliğini önbelleğe al (tablo görünümü bunu sık sık isteyebilir)
  2. Tabloda kullanılan görüntüler için en az kullanılan önbellek oluşturun (ve bir bellek uyarısı aldığınızda tüm etkin olmayan girişleri geçersiz kılın)
  3. Her şeyi çizin UITableViewCell's drawRect:eğer pahasına önlemek mümkün subviews (veya standart erişilebilirlik işlevselliğini gerektiriyorsa, içerik görünümü en drawRect:)
  4. UITableViewCellKatmanınızın opak olmasını sağlayın (aynısı, varsa içerik görünümü için de geçerlidir)
  5. ReusableCellIdentifier işlevini UITableViewörneklerde / belgelerde önerilen şekilde kullanın
  6. Kaçının gradyanları / komplike grafik efektleri içine pişmiş ön değildir UIImages

5
Ek olarak, indirilen resimler, hücrede görüntülenmeden önce imageView boyutuna küçültülmelidir!
Zoltán Matók

4
Bu yanıta, son birkaç yıldaki deneyimlerimi de eklemek istiyorum - şeffaf hücrelere sahip olmak muhtemelen hiçbir zaman kötü kaydırma performansının nedeni değildir. ÇOK karmaşık hücrelere (20'den fazla alt görünüm) sahip bir uygulamamız var ve arka planı göstermek için hepsi şeffaf. Doğru optimizasyonlarla şeffaflık bir 3GS'de bile fark yaratmaz. Aslında, malzemeyi en çok yavaşlatan şey, tablo görünümünden çıkacak kadar hücre olmadan önce uç yüklemesiydi. Alt görünümleri kullanıyorsanız, verimli hiyerarşilere sahip olduğunuzdan emin olun ve drawRect'i kullanmanız gerekmez.
Accatyyc

@Accatyyc, görünüşe göre benim de aynı problemim var. Kuyruktan çıkarmak için yeterli hücre olmadığında küçük bir gecikme olur, 3-4 hücre kuyruğu çözüldüğünde kaydırma düzgün olur. Hücreleri önceden yüklemenin herhangi bir yolu var mı, böylece kaydırma sırasında NIB dosyalarını yüklememek ve sıradan çıkarılacak hücreler var mı?
Tiois

@Tiois Elbette var. Hücrelerin kuyruğunu açmanın eski yöntemini kullanmanız gerekir (sınıfları / uçları kaydetmeyin, ancak bunları dequeueCellWithIdentifier: nil döndürürse oluşturun). Bu şekilde, tablo görünümünüz var olmadan önce bir hücre kümesi oluşturabilirsiniz, örneğin daha önce bunlardan 20 tane oluşturabilirsiniz. Sonra cellForRowAtIndexPath: 'de yenilerini oluşturmak yerine, onları boşalana kadar önce kendi önbelleğinizden çekersiniz.
Accatyyc

UICollectionView kullanıyorum ve aynı sorunla karşılaşıyorum. Özel hücre ucu dosyamda. Dikey UIstackView içinde UIwebView ve UIImageView dahil olmak üzere birkaç alt görünüm kullanıyorum. Listemi kaydırdığımda, yeniden kullanılan hücrelerin boyutlarını yeniden ayarlamak önemli ölçüde zaman alıyor ve kaydırma çok sarsıntılı görünüyor.
Mansuu ....

40
  1. Alt sınıf UITableViewCellyapıyorsanız, Uç kullanmayın, bunun yerine kodla yazın. Nib dosyalarını yüklemekten çok daha hızlıdır.
  2. Görüntüleri kullanıyorsanız, bunları önbelleğe aldığınızdan emin olun, böylece her biri için dosyadan bir kereden fazla yüklemeniz gerekmez (belleğiniz varsa - görüntülerin ne kadar yer kapladığına şaşıracaksınız).
  3. Mümkün olduğunca çok öğeyi opak yapın. Benzer şekilde, saydam olmayan resimleri kullanmayı deneyin.

3
Endişelenme ... bunlar trollerdi. mükemmel cevap!
Steav

79
Olumsuz oylar muhtemelen performansı artırmak için "uçlardan kaçın" ın kötü tavsiye olmasından kaynaklanıyordu. Hücreleri yeniden kullanıyorsanız, kaydırma sırasında hücreler uçlardan yeniden oluşturulmaz.
Steven Fisher

6
Uçlar hız olarak eşdeğerdir veya Cocoa with Love araştırmasına göre biraz daha hızlıdır. cocoawithlove.com/2010/03/…
MaxGabriel

Nib kullanan @Steven Fisher, örneğin hızlı kaydırma sırasında tablo allocs ve dealloc hücrelerinde daha yavaş olabilir.
Sound Blaster 13

3
Hücre inşa edilirken NIB'lerin kullanılması daha yavaş olabilir . Hücre geri dönüşümünü kullanıyorsanız, yalnızca ekranı doldurmaya yetecek kadar hücre vardır; diyelim, belki en fazla 10. Kaydırırken hücreler oluşturulmaz. Sadece yeniden kullanılırlar , ayrılmazlar ve yeniden tahsis edilmezler. Ve elbette, ayrıştırmanın hiçbir maliyeti yoktur. Yani hayır, bu doğru değil.
Steven Fisher

34

Tweetie'nin arkasındaki geliştirici, bu konuda kapsamlı bir şekilde yazdı ve bu uygulama için nasıl yapıldığını gösteren bazı kodlara sahip. Temel olarak, tablo hücresi başına bir özel görünümü savunur ve onu manuel olarak çizer (diğer seçeneklerin yanı sıra Arayüz Oluşturucu ile alt görüntüleme yapmak yerine).

hızlı-in-tweetie-ile-uitableview

Ayrıca Apple, TableViewSuite öğreticilerinde TableView için kendi örnek kodunu güncelledi (belki buna yanıt olarak?)

TableViewSuite


1
Bu harika bir çözüm. Merak ediyorum, cellView'e nasıl bir UIButton ekleyebilirim? DrawRect yönteminde mi çiziliyor?
Sukitha Udugamasooriya

1
@beno, bağlantınız bozuk görünüyor (ilki) elimizi orijinal makaleye koyma şansınız var mı?
apouche


orijinal sürüm bulunmadığından web arşivine bağlantı eklendi
Ralph Willgoss

1

UITableView kaydırmanın 1 numaralı performans katili, herhangi bir hücre görünümü katmanında gölgeler çizmektir, bu nedenle, kaydırma performansı önemliyse, temelde ana iş parçacığınızı yavaşlatmadığı sürece gölge yapmayın.

Kabul edilen cevapların hiçbiri gölgelerden ve katmanlardan bahsetmediği için bunun söylenmesi gerektiğini düşündü. : +)


6
eğer problemler gölgeler ise bu iki kod satırını ekler ve hepsi mükemmel çalışır self.layer.shouldRasterize = YES; self.layer.rasterizationScale = UIScreen.mainScreen.scale;
Pedro Romão

0

UITableViewKaydırma performansıyla ilgili herhangi bir sorun , diğer yanıtlarda zaten açıklanan teknikler kullanılarak çözülebilir. Bununla birlikte, çoğu zaman yavaş performans, doğası gereği hatalı veya tekrarlayan bir şeyden kaynaklanır.

Aslında UITableViewhücrelerini ve her hücre kendi imajını gerekebilir gerçeğini yeniden kullanır - Birlikte çözüm karmaşık bit yapar. Genel olarak nasıl çözüldüğünden, burada dikkat edilmesi gereken şeyleri özetliyorum:

  1. Verileri veri kaynağına yükleyin - REST / veritabanından. Bu adım, sonunda GCD kuyruğuyla birlikte dispatch_async kullanılarak arka planda yapılmalıdır.
  2. İlgili veri modeli nesnelerini oluşturun ve başlatın ve bunları bir dizinin içine yerleştirin
  3. [tableView reloaddata]
  4. İçeride cellForRowAtIndexPath, dizinin doğru veri modeli nesnesinden verileri (metin) ayarlayacak kodu ekleyin.
  5. Şimdi resimler de URL biçiminde olabilir, bu nedenle bu adım, tablo görünümü tarafından yapılan hücre yeniden kullanımı nedeniyle biraz tuhaf olabilir. İşin özü, eşzamansız sırayı kullanarak aygıt önbelleğinden / URL'den görüntüyü bir kez daha yüklemek, ardından doğru hücre.image (hücre görüntü özelliğiniz ne olursa olsun) olarak ayarlamaktır.

Sorunları önlemek için, tablo görünümünde resimlerin geç yüklenmesi hakkındaki bu eğiticiye bakın .

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.