2015-05-07 8 views
6

Güncel setini tekrar yüklendiğinde hareket:UITableView UITableViewAutomaticDimension ile FetchedResultsController powered by - Hücreler masa

TableView otomatik olarak hesaplanır yükseklikleri: zorlama sonuçları denetleyici güncellemeleri, veri zaman

self.tableView.sectionHeaderHeight = UITableViewAutomaticDimension; 
self.tableView.rowHeight = UITableViewAutomaticDimension; 
self.tableView.estimatedRowHeight = 152.0; 
self.tableView.estimatedSectionHeaderHeight = 50.0; 

tableview olduğunu yeniden yükleme:

- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller { 
    [self.tableView reloadData]; 
} 

Hücre, bir X kullanılarak yapılandırılır. ib. İlk etiket, hücrenin tepesine tutturulur, her biri aşağıdaki etiketin üstündeki etikete yapıştırılır ve alttaki etiket, hücrenin tabanına tutturulur.

Sayı:

i tablo görünümünde bir öğe üzerinde bir "favori" özelliğini ayarlayın Her seferinde, zorlama sonuçları denetleyici masa ve kaydırma konumunu yeniden ateşlenir değiştirilir. Düzeltmeye çalıştığım kaydırma konumundaki bu değişiklik. i hücre yükseklikleri sabit kullanılmıyorsa herhangi

Ek Bilgi

o sorunu çözer ANCAK ilk etiket iki satır üzerinde sarabilirsiniz ve kalan etiketleri veya mevcut olabilir veya olmayabilir çünkü ben UITableViewAutomaticDimension gerektirir.

Örnek

Not - i Fav düğmesini seçin olarak, Çekirdek verilerinde fav özelliğini ayarlar ve tablo yeniden yükler. Tablo neden zıplıyor?

enter image description here

cevap

7

Bunun nedeni aşağıdaki sekansın gerçekleşir:

  1. UITableView başlatıldı ve 5 hücreleri gösteren. Bu hücrelerin her birinin yüksekliği UITableView ile bilinir. Her bir hücreyi görüntülemeden önce, bir temsilcisini -tableView:heightForRowAtIndexPath: yöntemini çağırarak tam yükseklikte olmasını ister.
  2. UITableView, 3 hücreyi üstten kaydırdı. Bu hücrelerin yükseklikleri tam olarak [60, 70, 90] = 220 olarak bilinir. UITableView's contentOffset.y artık 220.
  3. UITableView yeniden yüklenir. Hücreler hakkındaki tüm bilgilerini temizler. Şimdi hala contentOffset.y olan 220'yi biliyor.
  4. UITableView, genel metrikler hakkında veri kaynağını soruyor - her bölümdeki bölüm sayısı ve satır sayısı.
  5. UITableView şimdi içeriğini doldurmaya başlıyor. İlk olarak, kaydırma göstergelerini doğru boyutlandırmak ve konumlandırmak için içeriğinin boyutunu bilmek gerekir. Ayrıca, hangi nesnenin - tablo üstbilgisi, bölüm üstbilgileri, satırlar, bölüm altbilgileri ve tablo altbilgisi - mevcut bounds, hangi konumun da contentOffset tarafından temsil edildiğini göstermesi gerektiğini bilmesi gerekir. Görünen nesneleri yerleştirmeye başlamak için, önce [0… 220] görünmez dikey aralığına düşen nesneleri atlamak gerekir.Eğer estimated… özelliklerden herhangi ilişkin değerleri vermediğiniz ve sonra tableViewController:estimated… yöntemlerden herhangi uygulanan UITableView böyle -tableView:heightForRowAtIndexPath: gibi uygun temsilci yöntemleri çağırarak üst bilgiler, alt ve satırların tam yüksekliği hakkında onun temsilci sorar olmadıysanız

    1. . Temsilciniz aynı sayıda nesneyi ve yeniden yüklemeden önce onlar için aynı yükseklikleri bildirirse, herhangi bir tablo öğesinin konumu ve boyutunda herhangi bir görsel değişiklik görmezsiniz. Bu "boğaz" davranışının dezavantajı, tablonuzun çok sayıda satır göstermesi gerektiğinde belirginleşti, 50000 diyelim. UITableView, bu 50000 satırın her birinin yüksekliğiyle ilgili delege sorar ve her bir karşılık gelen metninizi ölçerek kendiniz hesaplamanız gerekir. Nesne, veya UITableViewAutomaticDimension UITableView kullanırken, metnin doldurulduğu hücreler için kendi temsilci soran, aynı ölçümün kendisi yapıyor. İnan bana, yavaş. Her yeniden yükleme, birkaç saniye arayla donmaya neden olur.
    2. UITableView ürününü tahmini yükseklikler sağladıysanız, o zaman temsilcisinden yalnızca şu anda görünür nesnelerin yükseklikleri için bilgi verilecektir. [0… 220] dikey aralığındaki nesneler, satırlar için estimatedRowHeight veya -tableView:estimatedHeightForRowAtIndexPath:'da sağlanan değerler kullanılarak ve bölüm üstbilgileri ve altbilgileri için karşılık gelen yöntemler kullanılarak sayılır. estimatedRowHeight'u 60'a ayarlayarak, UITableView'e üç satırı atlamak (60 * 3 = 180) ve satır 4'ü üst görünen kenardan -40 ofsetiyle yerleştirmek için söylüyorsunuz. Bu nedenle 40 piksel yukarı görsel "atlama". reloadData aramamamı

burada bir "doğru" çözüm olacaktır. Satırları yalnızca değiştirilen nesneler için yeniden yükle, -reloadRowsAtIndexPaths:withRowAnimation: kullanın. NSFetchedResultsController + UITableView durumunda bu classic scheme kullanın.

+0

Mükemmel cevap, teşekkür ederim. Çok detaylı, bu iç işleri nasıl keşfettiniz? Dokümanlar'dan belli olmadığı için. Sadece bir hücreyi yeniden yükleyerek sorunu çözer. Bu aslında çökebilir bir UITableView uygulamasıdır, bu nedenle -reloadRowsAtIndexPaths sistem yöntemine karşılık gerekli hücre yapılandırmak için bir yöntem var: WithRowAnimation: –

+0

@bteapot: Ben benzer bir sorun var. Ancak, sayfalama yaptığımda ve sonra tablo görünümünü yeniden çağırdığında oluşur. Bu yeniden yüklendikten sonra, kaydırdığımda, yukarıdaki atlama gerçekleşir. Aşağı kaydırırken sorun yok. Lütfen bir çözüm öner. – krishnanunni

+1

@krishnanunni Tablo görünümünüzde "tableView: tahminiHeightFor…" veya "tahminiRowHeight"/"tahminiSayfa…" var mı? Gerçekten sayfalama ile buna ihtiyacınız var mı? Yalnızca büyük satır sayısıyla uygulanmaya değer, bu da sayfalandırma ile ilgili bir sorun olmamalıdır. Tahmini yükseklik kullanmamaya çalışın ve neler olduğunu görün. – bteapot