0

I am using this code to display image in to my customCell. This is my code to fetch image from API. It was working fine as per the given link. But the problem started when I added this code to my cellForItemAt indexPath: for image Cache.

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {

    // Displaying other elements with text

    customCell.mainImage.image = nil

    var image1 = self.imageCache.object(forKey: indexPath.item as AnyObject) as? UIImage

        if (image1 == nil) {
            self.ImageFetcher(postId: self.myArray[indexPath.item].id!, completion: { (image) in
            image1 = image
            self.imageCache.setObject(image1!, forKey: indexPath.item as AnyObject)
        })
    }
    DispatchQueue.main.async {
        customCell.mainImage.image = image1
    }
}

Above code works fine without any error but, not displaying/loading images until I scroll the collectionView up and down. Don't understand what I am missing here. Any help would be appreciated !!

iUser
  • 1,075
  • 3
  • 20
  • 49
  • `image1 = image` => `DispatchQueue.main.async { customCell.mainImage.image = image }` – Larme Aug 02 '17 at 16:02
  • I tried adding `customCell.mainImage.image = image` in `ImageFetcher` but then cell displays wrong images and then changes to correct image again when scrolling fast. – iUser Aug 02 '17 at 16:08
  • The reason why it's displaying the wrong image is because you didn't cancel the previous image load when the cell is being reused. – HMHero Aug 02 '17 at 16:24
  • I did try `override func prepareForReuse() { mainImage.image = nil super.prepareForReuse() }` in my customCell class but, no difference! – iUser Aug 02 '17 at 16:51
  • @Snehal i think your imageFetcher function in not good – Jaydeep Vyas Aug 03 '17 at 04:32
  • @Snehal use UIIMageView extension for more effective use – Jaydeep Vyas Aug 03 '17 at 04:46

2 Answers2

0

Please try this,

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {

    // Displaying other elements with text

    if let image1 = self.imageCache.object(forKey: indexPath.item as AnyObject) as? UIImage
    {
        customCell.mainImage.image = image1
    }
    else {
        self.ImageFetcher(postId: self.myArray[indexPath.item].id!, completion: { (image) in
            self.imageCache.setObject(image, forKey: indexPath.item as AnyObject)
            customCell.mainImage.image = image1
        })
    }
}
Kiester
  • 147
  • 1
  • 7
0

STEP:1 Create extension of uiimageview to download image from url, and if already downloaded then from cache

   let imageCache = NSCache()
    extension UIImageView {

    func loadImageUsingCacheWithURLString(url: NSURL) {

        self.image = nil

        // First check if there is an image in the cache
        if let cachedImage = imageCache.objectForKey(url) as? UIImage {

            self.image = cachedImage

            return
        }

        else {
        // Otherwise download image using the url location in Google Firebase
        NSURLSession.sharedSession().dataTaskWithURL(url, completionHandler: { (data, response, error) in

            if error != nil {
                print(error)
            }
            else {
                dispatch_async(dispatch_get_main_queue(), {

                    // Cache to image so it doesn't need to be reloaded every time the user scrolls and table cells are re-used.
                    if let downloadedImage = UIImage(data: data!) {

                        imageCache.setObject(downloadedImage, forKey: url)
                        self.image = downloadedImage

                    }
                })
            }
            }).resume()
        }

    }

STEP 2 : Usage

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {

    // Displaying other elements with text
    customCell.mainImage.loadImageUsingCacheWithURLString(url: yoururl)
 }
Jaydeep Vyas
  • 4,411
  • 1
  • 18
  • 44