2015-07-23 1 views
3

Je travaille avec un UICollectionView et j'ai actuellement des cellules en plein écran et lorsque je glisse vers la cellule suivante, l'image prend un peu à charger dans la cellule (puisqu'elles sont en haute résolution) . J'utilise déjà PHCachingImageManager pour mettre en cache l'image avant la main et elle est déjà mise en cache avant de charger la cellule, mais le chargement de l'image dans l'imageView prend un peu de temps. Je me demandais s'il y avait un moyen de précharger la cellule suivante invisible AVANT qu'il arrive à cellForItemAtIndexPath?Précharger la cellule suivante (actuellement invisible) UICollectionView

Des pensées?

Répondre

1

Apparemment, le chargement d'une image qui a déjà été mise en cache à partir du gestionnaire PHCachingImageManager a été la cause de mon retard. J'ai créé une fonction de test qui a sauvegardé l'image suivante (et ajoutera la précédente) dans une propriété lors de la configuration de la cellule en cours et mon scintillement n'est plus. Je posterai l'exemple de travail quand je l'ai fait le ménage ...

Mise à jour: Je créé un _images NSMutableDictionary pour stocker les images déjà chargées et le remplir en utilisant cette fonction

- (void)startCachingSurroundingImages:(NSInteger)index { 
CGSize targetSize = PHImageManagerMaximumSize; 
PHImageRequestOptions *options = [[PHImageRequestOptions alloc] init]; 
[options setNetworkAccessAllowed:YES]; 
[options setDeliveryMode:PHImageRequestOptionsDeliveryModeHighQualityFormat]; 

if (index < _imagesArray.count - 1 && ![_images objectForKey:[NSIndexPath indexPathForItem:0 inSection:index+1]]) { 
    NSDictionary *assetDictionary = [_imagesArray objectAtIndex:index + 1]; 
    NSString *assetRefID = [assetDictionary objectForKey:@"asset_id"]; 

    PHFetchResult *assetFetchResult = [PHAsset fetchAssetsWithLocalIdentifiers:@[assetRefID] options:[PHFetchOptions new]]; 
    PHAsset *asset = [assetFetchResult firstObject]; 



    [photoManager requestImageForAsset:asset targetSize:targetSize contentMode:PHImageContentModeAspectFit options:options resultHandler:^(UIImage *result, NSDictionary *info) { 
     if (result) { 
      [_images setObject:result forKey:[NSIndexPath indexPathForItem:0 inSection:index+1]]; 
     } 
    }]; 
} 

if (index - 1 >= 0 && ![_images objectForKey:[NSIndexPath indexPathForItem:0 inSection:index-1]]) { 
    NSDictionary *leftAssetDictionary = [_imagesArray objectAtIndex:index - 1]; 
    NSString *leftAssetRefID = [leftAssetDictionary objectForKey:@"asset_id"]; 

    PHFetchResult *leftAssetFetchResult = [PHAsset fetchAssetsWithLocalIdentifiers:@[leftAssetRefID] options:[PHFetchOptions new]]; 
    PHAsset *leftAsset = [leftAssetFetchResult firstObject]; 

    [photoManager requestImageForAsset:leftAsset targetSize:targetSize contentMode:PHImageContentModeAspectFit options:options resultHandler:^(UIImage *result, NSDictionary *info) { 
     if (result) { 
      [_images setObject:result forKey:[NSIndexPath indexPathForItem:0 inSection:index-1]]; 
     } 
    }]; 
    } 
} 

que j'appelle à cellForItemAtIndexPath comme si ...

[self startCachingSurroundingImages:indexPath.section]; 

et encore cellForItemAtIndexPath, je charge l'image comme si ... 01

if ([_images objectForKey:indexPath]) { 
    cell.imageView.image = [_images objectForKey:indexPath]; 
    [photoCell.activityIndicator setHidden:YES]; 
} else { 
    photoCell.tag = (int)[photoManager requestImageForAsset:asset targetSize:targetSize contentMode:PHImageContentModeAspectFit options:options resultHandler:^(UIImage *result, NSDictionary *info) { 
     PhotoCell *photoCell = (PhotoCell *)[self.collectionView cellForItemAtIndexPath:indexPath]; 
     if (photoCell && result) { 
      photoCell.imageView.image = result; 
      [photoCell.activityIndicator setHidden:YES]; 
     } else { 
      NSLog(@"BAD IMAGE!!! %@", info); 
      [photoCell.activityIndicator setHidden:NO]; 
     } 
    }]; 
} 

Puis dans didReceiveMemoryWarning nettoyer un peu ...

- (void)didReceiveMemoryWarning { 
    NSArray *allKeys = [_images allKeys]; 
    for (int i = 0; i < _images.count; i++) { 
    NSIndexPath *path = [allKeys objectAtIndex:i]; 
    if (path.section != _lastIndex && path.section != _lastIndex - 1 && path.section != _lastIndex + 1) { 
     [_images removeObjectForKey:path]; 
    } 
    } 
    // Though one could just as easily do this 
    // [_images removeAllObjects]; 
} 

Il est pas joli, mais ça fonctionne.