I have done similar task, showing the images on the table and resize the tableview cell so that the image is shown along the fullscreen width
Height For Row At IndexPath
var cachedHeight = [IndexPath : CGFloat]()
override func tableView(_ tableView: UITableView, heightForRowAtindexPath: IndexPath) -> CGFloat {
let default_height : CGFloat = 332.0
// lookup for cached height
if let height = cachedHeight[indexPath]{
return height
}
// no cached height found
// so now try for image so that cached can be calculated and cached
let cache : SDImageCache = SDImageCache.shared()
let image : UIImage? = cache.imageFromDiskCache(forKey: self.viewModel?.getProductImage(of: indexPath.row, at: 0))
if let image = image{
let baseHeight : CGFloat = CGFloat(332 - 224) // cell height - image view height
let imageWidth = self.tableView.frame.size.width
let imageHeight = image.size.height * imageWidth / image.size.width
cachedHeight[indexPath] = imageHeight + baseHeight
return cachedHeight[indexPath]!
}
//
// even if the image is not found, then
// return the default height
//
return default_height
}
Cell For Row At IndexPath
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let sdCache = SDImageCache.shared()
let cell = tableView.dequeueReusableCell(withIdentifier: "MyXYZCell", for: indexPath) as! AuctionListTableViewCell
let imageURL = self.viewModel?.getProductImage(of: indexPath.row, at: 0)
if let imageURL = imageURL {
if (sdCache.imageFromCache(forKey: imageURL) != nil) {
//
// image data already persist on disk,
// cell height update required
//
cell.auctionImageView.sd_setImage(with: URL.init(string: imageURL), completed: nil)
}
else
{
cell.auctionImageView.sd_setImage(with: URL.init(string: imageURL), completed: { (image, err, cacheType, url) in
self.tableView.reloadRows(at: [indexPath], with: UITableViewRowAnimation.none)
})
}
}
//other cell customization code
return cell
}
I have used SDWebImage. You can use it, or find similar api in AFNetworking
.
Keynotes:
- Here
cachedHeight
is used to cache the height of the cell indexed by the IndexPath
, because reading the image from the disk is quiet I/O exhaustive task, which results lag in the table view scroll.
- In
heightForRow
i checked that, is the image is in cache, if in cache, then calculate the height, store it into the cachedHeight
, otherwise return the default height. (My default height is calculated for my placeholder image)
- In the
cellForRowAtIndexPath
i have checked is the image is in cache. If the image is in cache, then no reload is required as the height is already calculated. Otherwise i attempt a network fetch, when the fetch completed i request to tableview to reload that cell.
Hope it helps, Happy coding.