2012-05-01 22 views
9

UIImageView ve UILabel'den oluşan özel bir UITableViewCell var. Hücre 320x104 pikseldir ve imageView, ön taraftaki etiketle tüm alanı kaplar. Sadece 8 hücre var.Özel UITImaViewCell büyük UIImageView ile kaydırma gecikmesine neden oluyor

ViewDidLoad İçinde tüm gerekli görüntüleri ön tarafa oluşturuyorum ve bunları bir sözlükte doğru boyutlarda önbelleğe alıyorum.

UITableView öğesini kaydırdığımda, yeni bir hücre her karşılaşıldığında fark edilebilir bir gecikme var. Bu, benim kullandığım görüntü zaten oluşturulduğu ve önbelleğe alındığı için hiçbir anlam ifade etmiyor. Hücreyi istediğim her şey, UIImageView görüntüsünü görüntüyü oluşturmak içindir.

Bir xib onun manzaralı bir özel hücre kullanarak ve bunu kullanmak benim UITableView yapılandırarak ediyorum:

[self.tableView registerNib: [UINib nibWithNibName: "ActsCell" paket @: nil] forCellReuseIdentifier: myIdentifier];

Hücre oluşturma ve yapılandırma:

- (UITableViewCell *)tableView:(UITableView *)tableView 
     cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    NSString* reuseIdentifier = @"ActsCell"; 
    ActsCell* cell = [tableView dequeueReusableCellWithIdentifier:reuseIdentifier]; 
    // Configure the cell... 
    [self configureCell:cell atIndexPath:indexPath]; 
    return cell; 
} 

- (void)configureCell:(ActsCell *)cell atIndexPath:(NSIndexPath *)indexPath 
{ 
    Act* act = [self.acts objectAtIndex:indexPath.row]; 
    cell.selectionStyle = UITableViewCellSelectionStyleNone; 
    cell.title.text = act.name; 
    cell.imageView.image = [self.imageCache objectForKey:act.uid]; 
} 

gecikmeye neden ne olabilir? Zaman yoğun bir çalışma yapıldığından Async'in hiçbir şey yapmaya çalışmasında hiçbir yararı yok gibi görünüyor.

+0

İki şey düşünebilirim. Bir tanesi, "reusableIdentifier" ı doğru şekilde ayarlamamanız nedeniyle dequeueing'in başarısız olmasıdır. Diğeri, görüntülerin boyutudur. Görüntüler yüklendiyse de, CG görüntü vermeden önce görüntü verisini işlemeye ihtiyaç duyar, bu da ölçekleme, birleştirme vb. Gibi maliyetli işlemleri içerebilir. – Lvsti

+0

@Lvsti Yeniden kullanıcı tanımlayıcıyı doğru şekilde ayarlamadığımı nasıl detaylandırabilir misiniz? – Undistraction

+0

Eğer o, dequeueing yaparken ben if (hücreyi == nil) kullanmayın demek durumunda aksi takdirde {// hücreyi Oluştur} ... geri – Lvsti

cevap

28

Görüntüleri yerel dosyalardan herhangi bir şansla yüklüyor musunuz?

Aletleri kullanarak, UIImage'da bir tembel yükleme mekanizması olduğunu buldum - gerçek görüntü verileri, sadece kaydırma sırasında gecikmeye neden olan ana iş parçacığı üzerinde oluşturma aşamasında PNG'den açıldı.

Yani, -initWithContentsOfFile: yöntemle UIImage yüklenmesinden sonra, ben ekran dışında bağlamda bu görüntünün içeriğini işlemek için kodunu ekledim yeni UIImage olarak bu bağlam kaydedilir ve UITableViewCell yılında UIImageView için kullandı, bu kaydırma yapılan Göze tekrar pürüzsüz ve hoş ol. referans olması halinde

I (ARC kullanarak) ayrı iplik görüntü içeriklerinin okunmasını zorlamak için kullanıyorum basit kod vardır:

UIImage *productImage = [[UIImage alloc] initWithContentsOfFile:path]; 

CGSize imageSize = productImage.size; 
UIGraphicsBeginImageContext(imageSize); 
[productImage drawInRect:CGRectMake(0, 0, imageSize.width, imageSize.height)]; 
productImage = UIGraphicsGetImageFromCurrentImageContext(); 
UIGraphicsEndImageContext(); 

Ve bence şekilde oluşturulan UIImage yüzeyi oluşturma işlemi için uygun desteklenen formatta olacak, bu da ana iş parçacığı üzerinde işlemek için gereken işleri de kaldıracaktır.

DÜZENLEME: UIGraphicsGetImageFromCurrentImageContext() için dokümanlar, yalnızca ana iş parçacığından kullanılmasının gerektiğini, ancak ağda veya SO üzerinde arama yapmanın, iOS 4'ten başlayarak UIGraphics.. yöntemlerinin iş parçacığı için güvenli olduğunu gösterdiğini gösterir.

+5

Bu kesinlikle benim için çok değerliydi. Bir fotoğrafı görüntülemek için her bir hücrede UIImageViews ile UICollectionView üzerinde titrek kaydırma yaşadım. Çok fazla * farklı çözümler denedim ama 60FPS'ye yaklaşmanın tek yolu aşırı derecede haylazdı. Denediğim çözümlerin çoğu, imageWithContentsOfFile kullanarak UIImages'nin bir NSCache'sini önyüklemeyi içeriyordu, ancak benim yaptığım her neyse, yukarıdaki kodu uygulayana kadar yeni hücreler ekranda geldikçe her zaman küçük bir sıçrama oldu. Dediğiniz gibi, dokularda belirtilmeyen imageWithContentsOfFile içine yerleştirilmiş bir çeşit tembel yükleme mekanizması olmalıdır. – alistairholt

+0

Bu çalışma benim için, indirilen veri yerine UIImage'ı sakladıktan sonra çok daha yumuşaktır, ardından her kullanılışında UIImage'a dönüştürülür. Çok teşekkür ederim. – Envil

+0

Yavaş/takıntılı sebep için çok uzun zamandır arama yapıyordum. Siz bir kahramansınız – user1838169

İlgili konular