简体   繁体   中英

What is the simplest way to insert resized images from Core Data into a UICollectionView?

When I set images from a local array into each collection view cell, scrolling is laggy. This is because the full scaled UIImage is being used when the cell will be displayed.

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

    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "PhotoCell", for: indexPath) as! PhotoCell

    let image = images[indexPath.row]
    cell.imageView.image = image

    return cell
} 

In order to try and solve this, I wrote a method that resizes images to their proper size at runtime.

private func resizeImages(images: [UIImage], size: CGSize) -> [UIImage?] {//...}

But resizing all the images in the array in viewDidLoad took a considerable amount of time.

This is a simple photo album app so I would prefer avoiding any use of activity or loading indicators. Given access to image data fetched from Core Data, how can I set the images in a collection view such that it won't lag while scrolling?

Instead of resizing images on runtime you should do this task at time of saving in CoreData . Instead of saving one image, you should store two images. One with full scale (high resolution) and other thumbnail (resized). Load only thumbnails in your CollectionViewCell to avoid scroll lagging.

I have used a LazyImageView (originally taken from cocoanetics.com ) for networking which probably work without many changes in your case:

import UIKit

class LazyImageView: UIImageView {
    var loading = false
    weak var rawImage: UIImage?

    deinit {
        image = nil
        loading = false
    }

    override func didMoveToSuperview() {
        if !loading && image == nil{
            loading = true
            DispatchQueue.global().async {
                self.resizeImage()
            }
        }
    }

    func resizeImage() {
        let resizedImage: UIImage? = nil
        // do the resizing
        DispatchQueue.main.async {
            self.image = resizedImage
            self.loading = false
        }
    }
}

As you have asked for simple I would consider it done.

If you want to spend some more time, you could/should think about caching (ie to the file system's cache folder).

Depending on the app, maybe you have another nice UX way to give the user a hint what will happen (ie setting correct(?) placeholder color as a background for the image before loading).

Considering @Bilal answer to save a correct thumb version sound also well. It really depends on your app, ie if the user has a choice to resize the overall image size in the collection view (now or as a future feature).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM