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:
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.