1

I have one cell in which i show images download from server now. Right now i show image with static height but now i want to make dynamic like facebook and instagram. For example if i upload image 320 * 100 then my cell need to become 300*100. and also suggest server side changes if required I am using afnetworking image loading classes.

Here is my cell design . enter image description here

EDIT: I tried given solution but now issue is that cell resize with jerk when second time it's come in cellforindexpath method. This will happen in first cell only.

Chirag Shah
  • 3,034
  • 1
  • 30
  • 61

2 Answers2

4

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:

  1. 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.
  2. 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)
  3. 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.

Ratul Sharker
  • 7,484
  • 4
  • 35
  • 44
  • Yes i tried your solution but i have one issue you calculate height of the contact but i used UITableViewAutomaticDimension, So first time image load with default height and when it reload then with jerk it become bigger. So is there any way to stop that jerk. – Chirag Shah Apr 17 '18 at 11:04
  • to stop the jerking use `self.tableView.reloadRows(at: [indexPath], with: UITableViewRowAnimation.automatic)` and go to the interface builder, select the tableview, in the `size inspector` section uncheck the `Row height` Automatic option and uncheck the `Estimate` option. Another thing, please clarify how did you use the `UITableViewAutomaticDimension`. I mean where & how did you set it ? – Ratul Sharker Apr 17 '18 at 16:30
  • 1
    Finally it's done , jerking gone when i set height of collection view in cellForRow, and charm it's working – Chirag Shah Apr 18 '18 at 05:08
2

I have solved this problem. If you have to make imageview height and width dynamic then ask server to send image width and Height in API response. Once you get both, according to image width and screen width calculate the image height. Take constraint of image height. And assign calculated height to image height constraint.

To calculate image height use below formula:-

imageHeight =  (screen_width * actual_image_height) / actual_image_width
Manish Mahajan
  • 2,062
  • 1
  • 13
  • 19