Chargement des images dans les cellules

Bonjour à  tous,


 


Actuellement j'utilise la méthode suivante pour le chargement des images dans des cellules :


 


http://jamesonquave.developpez.com/tutoriels/swift/debuter-developper-applications-ios-8/chargement-asynchrone-image-mise-en-cache/


 


pas de souci de lenteur, cela fonctionne.


 


En revanche dans la plupart des applications, le chargement d'image n'a pas le même comportement. Le chargement se fait en douceur.


dans la technique ci-dessus il arrive ceci :


tant que l'image n'est pas chargée, furtivement on voit une image d'une cellule qui ne correspond pas à  celle qui devrait apparaà®tre.


 


Quelle technique utilisez-vous ? Est-ce que des tutos existent sur ces autres techniques ?


 


Merci.


 


 


Réponses

  • J'ai une solution en Obj-C mais c'est le même principe en Swift.


     


    L'idée c'est de mettre toutes les url des images dans un array photos. 


    Ensuite tu créé ta propre class UITableViewCell dans. Tu auras au moins deux propriétés : une imageView et l'url d'une image.


    Tu implémentes la méthode setPhoto comme ça 



    -(void)setPhoto:(NSString *)photo{
    _photo = photo;
    [THPhotoController imageForPhoto:photo completion:^(UIImage *image) {
    self.imageView.image = image;
    }];
    }

    Puis dans une classe qu'ici s'appelle THPhotoController tu utilises la méthode imageForPhoto



    + (void)imageForPhoto:(NSString *)photo completion:(void(^)(UIImage *image))completion{

    if(photo == nil || completion == nil){ // Security
    return;
    }

    NSString *key = [NSString stringWithFormat:@%@",photo];
    UIImage *image = [[SAMCache sharedCache]imageForKey:key]; // like sharedSession
    if(image){ // if the photo was watched before, we use it directly
    completion(image);
    }
    else{ // We download it
    NSURL *url = [[NSURL alloc]initWithString:photo];
    NSURLSession *session = [NSURLSession sharedSession];
    NSURLRequest *request = [[NSURLRequest alloc]initWithURL:url];
    NSURLSessionDownloadTask *task = [session downloadTaskWithRequest:request completionHandler:^(NSURL * _Nullable location, NSURLResponse * _Nullable response, NSError * _Nullable error) {
    NSData *data = [NSData dataWithContentsOfURL:location];
    UIImage *image = [[UIImage alloc]initWithData:data];
    [[SAMCache sharedCache]setImage:image forKey:key]; // We cache the image because it's the first time we downlaod it
    dispatch_async(dispatch_get_main_queue(), ^{ //imageView is intended to be called in the main queue
    completion(image);
    });
    }];
    [task resume];
    }
    }

    Voila après dans cellForItemAtIndexPath t'as plus qu'a écrire


    cell.photo = self.photos[indexPath.row];


  • CéroceCéroce Membre, Modérateur
    janvier 2016 modifié #3

    dans la technique ci-dessus il arrive ceci :
    tant que l'image n'est pas chargée, furtivement on voit une image d'une cellule qui ne correspond pas à  celle qui devrait apparaà®tre.

    C'est normal. Dans le code donné en exemple, on utilise dequeueReusableCell... qui comme son nom l'indique renvoie une cellule "recyclée". C'est donc le contenu précédent de la cellule qui apparait. Ce qu'il faut faire: quand l'image n'est pas encore dans le cache, lancer la requête réseau, et afficher une image par défaut, dite "placeholder".

    Par ailleurs, la méthode employée " utiliser un dictionnaire pour stocker les images " est assez mauvaise. ça fait grimper la consommation mémoire inutilement. Une bonne implémentation définit une taille maximale du cache et purge les images qui n'ont pas été utilisées récemment.

    Donc, personnellement, j'utilise plutôt un truc comme SDWebImage, dispo via Cocoapods.
  • heliohelio Membre
    janvier 2016 modifié #4

    Merci !


    j'ai vu un tuto sur Alamofire et notamment ce code :



    Alamofire.request(.GET, url).response() {
    (_, _, data, _) in

    let image = UIImage(data: data!)
    cell.myImageView.image = image
    }


    Quelle sont les différences entre SDWebImage et Alamofire au niveau du chargement d'images ?


    J'ai testé les 2, par rapport au nombre d'éléments que j'affiche je ne vois pas de différence.


     


    Merci


  • CéroceCéroce Membre, Modérateur
    SDWebImage ne fait que ça, alors que Alamofire fait tout plein de trucs. Si tu n'as besoin que de charger des images, alors prend SDWebImage.
  • OK merci !


Connectez-vous ou Inscrivez-vous pour répondre.