J'ai une galerie dans mon application utilisant une UICollectionView
. Les cellules ont une taille approximative de 70,70. J'utilise ALAssets
de la ALAssetLibrary
dans la galerie que j'ai stockée dans une liste.
J'utilise le modèle habituel pour remplir les cellules:
-(UICollectionViewCell*)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
mycell = [collectionView dequeueReusableCellWithReuseIdentifier:cellIdentifier forIndexPath:indexPath];
mycell.imageView.image = [[UIImage imageWithCGImage:[alassetList objectAtIndex:indexpath.row] thumbnail]];
return mycell;
}
Ma galerie défile saccadée. Je ne comprends pas pourquoi c'est. J'ai essayé d'ajouter un NSCache pour mettre en cache les images miniatures (en pensant que la création des images était coûteuse), mais cela n'a pas aidé pour la performance.
Je m'attendrais à ce que l'interface utilisateur soit aussi crémeuse que l'application boursière.
Je soupçonne maintenant que cela peut être quelque chose dans le UICollectionViewCell prepareForReuse
qui peut retenir la méthode dequeueReusableCellWithReuseIdentifier
mais en utilisant des instruments, je n'ai pas pu le trouver.
Toute autre chose qui peut être la cause de cela? Existe-t-il un moyen "plus rapide" de préparer la UICollectionViewCell
ou de la dequeue
de manière plus rapide?
Donc, toute personne ayant des problèmes de défilement doit faire ceci
ajoutez ces 2 lignes après votre retrait
cell.layer.shouldRasterize = YES;
cell.layer.rasterizationScale = [UIScreen mainScreen].scale;
Je suppose que "choppyness" provient de l'allocation UIImage, et non de la méthode dequeueReusableCellWithReuseIdentifier
. J'essaierais de faire l'allocation des images sur un fil de fond pour voir si cela rend les choses un peu plus difficiles.
-(UICollectionViewCell*)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
mycell = [collectionView dequeueReusableCellWithReuseIdentifier:cellIdentifier forIndexPath:indexPath];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^(void) {
// Load image on a non-ui-blocking thread
UIImage *image = [[UIImage imageWithCGImage:[alassetList objectAtIndex:indexpath.row] thumbnail]];
dispatch_sync(dispatch_get_main_queue(), ^(void) {
// Assign image back on the main thread
mycell.imageView.image = image;
});
});
return mycell;
}
Plus de détails peuvent être trouvés ici: https://developer.Apple.com/library/ios/documentation/Cocoa/Conceptual/Multithreading/Introduction/Introduction.html
Chargez vos images en utilisant le sendAsynchronousRequest:queue:completionHandler:
de NSURLConnection
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:urlString]];
[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
[cell.imageView setImage:[UIImage imageWithData:data]];
}];
Cochez les sous-vues de clips et opaque dans l'inspecteur d'attributs, puis cochez la case Paging.
J'ai eu des problèmes avec le défilement UICollectionView
.
Ce qui a fonctionné (presque) comme un charme pour moi: j'ai rempli les cellules avec des vignettes en png 90x90. Je dis presque parce que le premier parchemin complet n’est pas aussi lisse, mais n’est plus écrasé ...
Dans mon cas, la taille de la cellule est 90x90.
J'avais beaucoup de formats png originaux auparavant, et c'était très agité quand la taille originale des png était supérieure à ~ 1000x1000 (beaucoup de crashs au premier défilement).
Donc, je sélectionne 90x90 (ou similaire) sur la UICollectionView
et affiche les pngs d'origine (peu importe la taille). J'espère que cela aide les autres.
Si quelqu'un utilise PhImageManager, le fait de désactiver Synchrone a résolu le problème. (deliveryMode = .FastFormat peut également améliorer les performances, mais le compromis est que la vignette sera de qualité inférieure)
let option = PHImageRequestOptions()
option.deliveryMode = .Opportunistic
option.synchronous = false
PHImageManager().requestImageForAsset(phAsset, targetSize: CGSizeMake(2048, 2048), contentMode: .AspectFit, options: option, resultHandler: { (image, objects) in
self.imageView.image = image!
})