1
votes

Swift UITableViewCell - L'image de la cellule change si je fais défiler trop rapidement, mais seulement à la première tentative

J'analyse un JSON dans ma méthode viewDidLoad. L'une des clés de ce JSON est l'URL de l'image, qui va dans un tableau de chaînes appelé "allCImages"

Ceci est juste une chaîne. Par conséquent, pour remplir l'image dans la cellule, dans ma méthode cellForRowAt, j'ai ce qui suit:

extension UIImageView {
    func downloadImage(from imgURL: String!) {
        let theUrl = URLRequest(url: URL(string: imgURL)!)

        // set initial image to nil so it doesn't use the image from a reused cell
        image = nil

        // check if the image is already in the cache
        if let imageToCache = vc1ImageCache.object(forKey: imgURL! as NSString) {
            self.image = imageToCache
            print("Image is in Cache")
            return
        }

        // download the image asynchronously 
        let task = URLSession.shared.dataTask(with: theUrl) { (data, response, error) in
            if error != nil {
                print(error!)
                return
            }

            DispatchQueue.main.async {
                // create UIImage
                let imageToCache = UIImage(data: data!)
                // add image to cache
                vc1ImageCache.setObject(imageToCache!, forKey: imgURL! as NSString)
                self.image = imageToCache
            }
        }

        task.resume()
    }

Remarque: vcCellImage est l'IBOutlet de la vue d'image de ma cellule.

La méthode "downloadImage" fait partie de l'extension suivante:

cell.vcCellImage.downloadImage(from: allCImages[indexPath.section])

Cela fonctionne presque parfaitement . Par exemple:

1) Si je fais défiler lentement ma vue de tableau, toutes les cellules contiennent l'image correcte

2) Si je fais défiler mon tableau, lentement ou rapidement, toutes les cellules contiennent l'image correcte. Cela est prouvé par le fait que ma console imprime ce qui suit:

  • L'image est dans le cache
  • L'image est dans le cache
  • L'image est dans le cache

Ie, la tableview obtient mon image du cache (puisque pour faire défiler vers le haut, je dois avoir fait défiler vers le bas avant)

3) Le problème est que je fais défiler mon tableau très rapidement, dès la première tentative. Comme l'image n'a pas encore été mise en cache, la cellule affichera la mauvaise image, avant de passer à l'image correcte. Problème classique

Par conséquent, il me manque ce petit morceau de logique. Comment résoudre ce problème?


EDIT: j'ai essayé ceci mais le problème demeure:

  • classe VCTableViewCell: UITableViewCell {

    override func prepareForReuse () {super.prepareForReuse () vcCellImage.image = nil}


0 commentaires

3 Réponses :


0
votes

J'ai été confronté à un problème similaire. J'ai résolu ce problème en annulant la demande d'image dans la méthode prepareForReuse . Pouvez-vous essayer la même chose?


3 commentaires

J'ai essayé mais le problème persiste: - class VCTableViewCell: UITableViewCell {override func prepareForReuse () {super.prepareForReuse () vcCellImage.image = nil}


hé @SteveJobs définissant l'image sur nil ne fonctionne pas, vous devez annuler l'URLRequest.


Ici, vous pouvez créer une variable de tâche URLSession de tâche dans VCTableViewCell et stocker la tâche pour chaque cellule correspondante, puis préparer la réutilisation do task.cancel ()



1
votes

Cela se produit à cause de

1- retrait de la cellule: les cellules sont réutilisées à l'intérieur du tableau

2- lorsque vous faites défiler avant qu'une requête ne se produise, cela peut provoquer un nouveau 1 avec la même URL

La meilleure option consiste à utiliser SDWebImage


0 commentaires

0
votes

tout d'abord si vous ajoutez votre API ou des données comme celle-ci, supprimez simplement ceci

var arr = [string]()

viewWillAppear()
{
arr.removeAll()
//call api
//append Data
arr.append("s","sd","sd)
}

accepte cela

var arr = [string]()

viewDidLoad()
{
arr.append("s","sd","sd)
}

J'ai un problème similaire alors je le résous comme ça, cela peut être utile pour vous aussi.


0 commentaires