Home > OS >  Scrolling in table view is glitchy and slow
Scrolling in table view is glitchy and slow

Time:09-17

I have the code below in my tableview cell to load users posts on the home feed. I am resizing the image to have a better control on the size of images that are displayed in the app. The code is working fine and the images are resized well. However this resizing processing is slowing down the post feed significantly and scrolling through the table view is now very glitchy.

Anyone have an idea on how to rewrite this in a more efficient way?

func set(post:Posts) {
    
    self.post = post
    
    // get PROFILE image
    let url = post.url
    profileImageView.sd_setImage(with: url, completed: nil)
    
    // get MEDIA image
    let mediaUrl = post.urlM
    MediaPhoto.sd_setImage(with: mediaUrl, completed: nil)
if let imageData: NSData = NSData(contentsOf: mediaUrl) {
       let image = UIImage(data: imageData as Data)
       let newWidth = MediaPhoto.frame.width
        let scale = newWidth/image!.size.width
      let newHeight = image!.size.height * scale
        UIGraphicsBeginImageContext(CGSize(width: newWidth, height: newHeight))
        image!.draw(in: CGRect(x: 0, y: 0, width: newWidth, height: newHeight))
            let newImage = UIGraphicsGetImageFromCurrentImageContext()
            UIGraphicsEndImageContext()
       MediaPhoto.image = newImage
    }

CodePudding user response:

It's not recommended to do heavy-weight jobs in cells like rendering or formatting, etc.

I suggest using kingfisher to download images and display them.

see more: Kingfisher

Which is contain some useful features like:

  • Asynchronous image downloading and caching.
  • Useful image processors and filters provided (Which is you need in this case)
  • And so many other features...

to resize images follow like below codes:

let resizingProcessor = ResizingImageProcessor(referenceSize: CGSize(width: 100.0 , height: 100.0))
let url = URL(string: path)
imageView.kf.indicatorType = .activity
imageView.kf.setImage(with: url,
                      options: [.processor(resizingProcessor)],
                      completionHandler: nil
)

for more info about resizing with kingfisher visit the below link:

Kingfishe Cheat-Sheet

CodePudding user response:

You should try using NSCache, I usually create an extensions file and create this method:

let imageCache = NSCache<AnyObject, AnyObject>()

extension UIImageView {
    
    func loadImageUsingCacheWithUrlString(_ urlString: String) {

        let strUniqueIdentifier_Initial = urlString
        self.accessibilityLabel = strUniqueIdentifier_Initial
        
        if let cachedImage = imageCache.object(forKey: urlString as AnyObject) as? UIImage {
            self.image = cachedImage
            return
        }
        
        guard let url = URL(string: urlString) else { return }
        URLSession.shared.dataTask(with: url, completionHandler: { (data, response, error) in
            
            if error != nil {
                print(error ?? "")
                return
            }
            
            let strUniqueIdentifier_Current = self.accessibilityLabel
            if strUniqueIdentifier_Initial != strUniqueIdentifier_Current {
                return
            }
            
            DispatchQueue.main.async(execute: {
                
                if let downloadedImage = UIImage(data: data!) {
                    imageCache.setObject(downloadedImage, forKey: urlString as AnyObject)
                    
                    self.image = downloadedImage
                }
            })
            
        }).resume()
    }
}

And then call the method like this:

// I usually use optional values when creating custom objects
if let imgUrl = post?.url {
   imgView.loadImageUsingCacheWithUrlString(imgUrl)
}

I personally like this option since I don't like using extra libraries.

  • Related