2010-12-08 63 views
3

Je travaille sur une application iPhone qui affiche des images miniatures à partir de contacts dans un UITableView.UITableView - chargement paresseux contact images

Tout est très rapide jusqu'à ce que j'allume les vignettes, alors il devient très lent à défiler. Toutes les autres données sont sauvegardées par Core Data et j'ai essayé d'enregistrer les images dans Core Data au préalable, mais cela prend trop de temps au lancement et est moins flexible etc.

Ce dont j'ai vraiment besoin, c'est d'une façon de faire la recherche et les miniatures de préparation paresseusement avec le fil séparé ou NSOperation etc., mais je ne suis pas sûr de ce que la manière la plus simple d'accomplir ceci serait.

Le projet d'exemple d'Apple LazyTableImages, qui est fantastique si les images proviennent du web, pourrait sûrement être adapté, même si j'ai du mal avec ça. Fondamentalement, le problème est le même, mais au lieu de retarder le téléchargement et la latence du réseau, etc, mon retard est juste le temps qu'il faut pour rechercher les images dans le carnet d'adresses de l'utilisateur.

Telle est la tâche dans ma sous-classe de cellule de tableau que je dois faire en même temps:

 UIImage *contactImage = nil; 
     if (ABPersonHasImageData(person)) { 

     NSData *contactImageData = (NSData*)ABPersonCopyImageData(person); 
     UIImage *tempContactImage = [UIImage imageWithData:contactImageData]; 
     [contactImageData release]; 

     UIGraphicsBeginImageContext(CGSizeMake(45.0f, 45.0f));    
     [tempContactImage drawInRect:CGRectMake(0.0f, 0.0f, 45.0f, 45.0f)];   
     contactImage = UIGraphicsGetImageFromCurrentImageContext(); 
     UIGraphicsEndImageContext(); 

     } 

Un grand merci à tous ceux qui ont des conseils utiles ou code pour ce faire d'une manière simple et élégante.

Répondre

1

Si vous avez déjà un UIImage, pourquoi avez-vous besoin de dessiner dans contactImage? Vous pouvez simplement utiliser le tempContactImage directement, non?

Un bon point de départ serait de faire simplement ceci:

cell.imageView.image = tempContactImage 

EDIT:

Que diriez-vous:

ABPersonRef person = ...get person... 
UITableViewCell * cell = ...get cell... 
[ [ NSOperationQueue mainQueue ] addOperation: 
    [ NSBlockOperation blockOperationWithBlock:^{ 
     if (ABPersonHasImageData(person)) { 
     ... 
     } 
     cell.imageView.image = contactImage ; 

    } ] ; 

Si c'est encore saccadé (il peut être), vous pouvez programmer le les images que vous devez appliquer à votre vue de table dans votre thread d'arrière-plan, attendez que la vue de votre table arrête de défiler, puis appliquez les modifications d'image en attente.

+0

Si vous dessinez dans contactImage juste à l'échelle pour s'adapter à 45.0x45.0, vous pouvez aussi utiliser le code ci-dessus et faire cell.imageView.contentMode = UIViewContentModeScaleAspectFill – nielsbot

+0

ABPersonCopyImageData (personne) CFDataRef imageData = ABPersonCopyImageDataWithFormat (personne, kABPersonImageFormatThumbnail); –

+0

Merci, mais si vous utilisez simplement: ABPersonCopyImageData (personne); Vous obtiendrez l'image de contact en taille réelle, quelle que soit cette taille. Cela effacera réellement une vue de table dans une application iPhone avec les utilisateurs qui ont des images de contact dans certains formats. Maintenant, nous devons utiliser la nouvelle fonction de mémoire inférieure beaucoup plus sûre: CFDataRef imageData = ABPersonCopyImageDataWithFormat (personne, kABPersonImageFormatThumbnail); –

1

Utilisez cette méthode. kABPersonImageFormat * Miniature *

(NSData*)ABPersonCopyImageDataWithFormat([targetPeople objectAtIndex:index], kABPersonImageFormatThumbnail)