2012-11-23 8 views
1

Je développe une galerie de photos et à cette fin, j'ai décidé d'utiliser PSTCollectionView (https://github.com/steipete/PSTCollectionView) qui implémente fondamentalement UICollectionView sur iOS6, et utilise une vue personnalisée pour les autres iOS. Mon appareil fonctionne sous iOS6. J'utilise le MKNetworkKit pour charger les images de mon serveur et utiliser la réponse mise en cache pour définir les images. La chose est, dès que je défile avec un minimum de vitesse, le défilement devient très laggy (ma conjecture en raison du réglage des images). Comme il semble, la cellule dequeued sont presque toujours la plupart du temps pas à droite indexPath, donc l'image est recréée à chaque fois. N'existe-t-il pas un moyen de rendre les cellules dequeue pour le bon chemin d'index et rechargé à partir de la mémoire (ou du cache) au lieu de réinitialiser l'image entière?UICollectionView très lent

Voici quelques bouquets de code:

La grille (i.e. UICollectionView) Attribution

PSUICollectionViewFlowLayout *layout = [[PSUICollectionViewFlowLayout alloc] init]; 
_gridView = [[PSUICollectionView alloc] initWithFrame:[self.view bounds] collectionViewLayout:layout]; 
_gridView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; 
_gridView.delegate = self; 
_gridView.dataSource = self; 
[_gridView registerClass:[ImageGridCell class] forCellWithReuseIdentifier:CollectionViewCellIdentifier]; 
[_gridView setAlwaysBounceVertical:YES]; 

Le cellForRowAtIndexPath:

ImageGridCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:CollectionViewCellIdentifier forIndexPath:indexPath]; 
id photoId = [self.photoIds objectAtIndex:indexPath.row]; 
[cell setPhotoId:photoId]; 
return cell; 

La méthode setPhotoId:

if (![_photoId isEqualToNumber:photoId]) 
{ 
    NSLog(@"set Photo ID %@ for old id %@", photoId, _photoId); 
    _photoId = photoId; 
    self.image.image = nil; 
    __block BOOL imageAlreadySetFromCache = NO; 
    self.operation = [[BDRWebService manager] downloadImageWithId:_photoId.stringValue 
                 isThumbnail:YES 
               completionHandler:^(UIImage *fetchedImage, NSURL *url, BOOL isInCache) { 
                if (isInCache && !imageAlreadySetFromCache) 
                { 
                 self.image.image = fetchedImage; 
                 NSLog(@"image ready %@ (from cache %d) %@", _photoId, isInCache, NSStringFromCGSize(self.image.image.size)); 
                 imageAlreadySetFromCache = YES; 
                } 
                else if (!imageAlreadySetFromCache) 
                { 
                 NSLog(@"image ready %@ (from cache %d) %@", _photoId, isInCache, NSStringFromCGSize(self.image.image.size)); 
                 self.image.image = fetchedImage; 
                } 
               } errorHandler:^(MKNetworkOperation *completedOperation, NSError *error) { 
               }]; 

} 
else 
{ 
    NSLog(@"same cell and image..."); 
} 

Voici le journal:

2012-11-23 11:39:25.431 cellForRow 12 
2012-11-23 11:39:25.433 set Photo ID 269 for old id (null) 
2012-11-23 11:39:25.436 cellForRow 13 
2012-11-23 11:39:25.437 set Photo ID 268 for old id (null) 
2012-11-23 11:39:25.440 cellForRow 14 
2012-11-23 11:39:25.441 set Photo ID 267 for old id (null) 
2012-11-23 11:39:25.463 cellForRow 15 
2012-11-23 11:39:25.468 set Photo ID 266 for old id 280 
2012-11-23 11:39:25.480 cellForRow 16 
2012-11-23 11:39:25.488 set Photo ID 265 for old id 281 
2012-11-23 11:39:25.490 cellForRow 17 
2012-11-23 11:39:25.504 set Photo ID 264 for old id 279 
2012-11-23 11:39:25.511 cellForRow 18 
2012-11-23 11:39:25.566 set Photo ID 263 for old id 276 
2012-11-23 11:39:25.570 cellForRow 19 
2012-11-23 11:39:25.580 set Photo ID 262 for old id 277 
2012-11-23 11:39:25.583 cellForRow 20 
2012-11-23 11:39:25.591 set Photo ID 261 for old id 278 
2012-11-23 11:39:25.654 cellForRow 21 
2012-11-23 11:39:25.659 set Photo ID 260 for old id 273 
2012-11-23 11:39:25.661 cellForRow 22 
2012-11-23 11:39:25.665 set Photo ID 259 for old id 274 
2012-11-23 11:39:25.667 cellForRow 23 
2012-11-23 11:39:25.671 set Photo ID 258 for old id 275 
2012-11-23 11:39:25.690 cellForRow 24 
2012-11-23 11:39:25.693 set Photo ID 257 for old id 270 
2012-11-23 11:39:25.696 cellForRow 25 
2012-11-23 11:39:25.700 set Photo ID 256 for old id 271 
2012-11-23 11:39:25.703 cellForRow 26 
2012-11-23 11:39:25.707 set Photo ID 255 for old id 272 
2012-11-23 11:39:25.733 cellForRow 27 
2012-11-23 11:39:25.737 set Photo ID 254 for old id 269 
2012-11-23 11:39:25.740 cellForRow 28 
2012-11-23 11:39:25.747 set Photo ID 253 for old id 267 
2012-11-23 11:39:25.758 cellForRow 29 
2012-11-23 11:39:25.776 set Photo ID 252 for old id 268 
2012-11-23 11:39:25.872 cellForRow 30 
2012-11-23 11:39:25.886 set Photo ID 251 for old id 264 
2012-11-23 11:39:25.890 cellForRow 31 
2012-11-23 11:39:25.894 set Photo ID 250 for old id 265 
2012-11-23 11:39:25.897 cellForRow 32 
2012-11-23 11:39:25.906 set Photo ID 249 for old id 266 

Il va comme ceci pour toujours (peut-être c'est le comportement approprié. Après tout, c'est ce que dequeue est tout à fait raison?), Mais puis-je faire le défilement plus rapide.

Je pourrais utiliser toutes sortes de conseils (en chargeant l'image avec une minuterie après 0,2 secondes et l'invalider dans la méthode prepareForReuse, annuler l'opération (j'ai essayé, rien de mieux jusqu'ici)), mais ce ne serait pas très agréable.

Comment puis-je rendre les images "coller" aux cellules pour éviter une nouvelle allocation self.image.image = fetchedImage à chaque fois?

Répondre

0

Je pense que le bloc s'exécutera dans un autre thread. Donc toutes les opérations liées à l'interface utilisateur doivent être effectuées sur le thread principal

dispatch_async(dispatch_get_main_queue(), ^{ 


     if (isInCache && !imageAlreadySetFromCache) 
      { 
      self.image.image = fetchedImage; 
      NSLog(@"image ready %@ (from cache %d) %@", _photoId, isInCache, NSStringFromCGSize(self.image.image.size)); 
      imageAlreadySetFromCache = YES; 
      } 
     else if (!imageAlreadySetFromCache) 
     { 
      NSLog(@"image ready %@ (from cache %d) %@", _photoId, isInCache, NSStringFromCGSize(self.image.image.size)); 
      self.image.image = fetchedImage; 
     } 

}); 
+0

J'ai essayé cela aussi, mais cela n'a pas fonctionné non plus :( – Khal

0

Vous devez utiliser PSCollectionViewFlowLayout_ au lieu de PSUICollectionViewFlowLayout, PSCollectionViewController_ au lieu de PSUICollectionViewController, etc.

Je pense que cela est parce que vous utilisez le contrôle PSTCollecitonView. Si vous avez besoin d'un support hérité pour iOS 5.1 PSTCollectionView tel quel, mais sur iOS 6, vous devez utiliser natif UICollectionView. Dans ce cas, peut-être PSTCollectionView sur iOS 5. * sera lent. Mais sur iOS 6.0, tout devrait bien se passer.

De la documentation officielle:

Vous voulez utiliser UICollectionView, mais ont encore besoin de soutenir plus versions d'iOS? Alors tu vas adorer ce projet.Au départ, je écrit pour PSPDFKit, mon cadre iOS PDF qui prend en charge le texte sélection et annotations, mais ce projet semblait trop utile pour les autres à garder pour moi :)

Si vous voulez avoir PSTCollectionView sur iOS4. 3/5.x et UICollectionView sur iOS6, utilisez PSUICollectionView (en gros, ajoutez PS sur à n'importe quelle classe UICollectionView * pour obtenir le support automatique des anciennes versions iOS ) Si vous voulez toujours utiliser PSTCollectionView, utilisez PSTCollectionView comme noms de classes. (remplacez l'interface utilisateur avec PST)

+0

Merci, je vais y jeter un coup d'oeil. – Khal