Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dynamic UIImageView Size Within UITableView

Tags:

I want to implement a TableView with a Custom TableViewCell showing an image.

To make this simple, I simply put a UIImageView inside a tableviewcell using autolayout (illustrated below). enter image description here

What I want is to display the image inside a UIImageView however those images dimensions can be anything and are inconsistent (portrait, landscape, square) ...

Therefore, I'm looking to display an image with a fixed width (the width of the device) and a dynamic height that respect the ratio of the images. I want something like this:
enter image description here

I unfortunately didn't manage to reach that result.

Here's how I implemented it - (I'm using Haneke to load the image from an URL - image stored in Amazon S3):

class TestCellVC: UITableViewCell {      @IBOutlet weak var selfieImageView: UIImageView!     @IBOutlet weak var heightConstraint: NSLayoutConstraint!      func loadItem(#selfie: Selfie) {                 let selfieImageURL:NSURL = NSURL(string: selfie.show_selfie_pic())!          self.selfieImageView.hnk_setImageFromURL(selfieImageURL, placeholder: nil, format: HNKFormat<UIImage>(name: "original"), failure: {error -> Void in println(error)             }, success: { (image) -> Void in                 // Screen Width                 var screen_width = UIScreen.mainScreen().bounds.width                  // Ratio Width / Height                 var ratio =  image.size.height / image.size.width                  // Calculated Height for the picture                 let newHeight = screen_width * ratio                  // METHOD 1                 self.heightConstraint.constant = newHeight                  // METHOD 2                 //self.selfieImageView.bounds = CGRectMake(0,0,screen_width,newHeight)                  self.selfieImageView.image = image             }         )     }      override func viewDidLoad() {         super.viewDidLoad()          // Register the xib for the Custom TableViewCell         var nib = UINib(nibName: "TestCell", bundle: nil)         self.tableView.registerNib(nib, forCellReuseIdentifier: "TestCell")          // Set the height of a cell dynamically         self.tableView.rowHeight = UITableViewAutomaticDimension         self.tableView.estimatedRowHeight = 500.0          // Remove separator line from UITableView         self.tableView.separatorStyle = UITableViewCellSeparatorStyle.None          loadData()     }      override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {         var cell = tableView.dequeueReusableCellWithIdentifier("TestCell") as TestCellVC           cell.loadItem(selfie: self.selfies_array[indexPath.row])         // Remove the inset for cell separator         cell.layoutMargins = UIEdgeInsetsZero         cell.separatorInset = UIEdgeInsetsZero          // Update Cell Constraints         cell.setNeedsUpdateConstraints()         cell.updateConstraintsIfNeeded()         cell.sizeToFit()          return cell     } } 

My calculation of the dynamic Height is correct (I've printed it). I've tried both method (describe in the code) but none of them worked:

  1. Set the Height Autolayout constraint of the UIImageView
  2. Modify the frame of the UIImageView

See Results of Method 1 and 2 here: imageImage 2

like image 663
fabdarice Avatar asked Aug 29 '15 01:08

fabdarice


People also ask

Does UIImageView have intrinsic content size?

Here is the essential problem: the only way in which UIImageView interacts with Auto Layout is via its intrinsicContentSize property. That property provides the intrinsic size of the image itself, and nothing more.

How do I change aspect ratio in UIImageView?

To maintain aspect ratio I calculated the width of UIImageView = (320/460)*450 = 313.043 dynamically. And set the contentMode For UIImageView is UIViewContentModeScaleAspectFit. And set the image(320x460) to image view but it is some what blur.


Video Answer


1 Answers

In the storyboard add trailing, leading, bottom and top constraints to your UIImageView. After you load your image all you need to do is add an aspect constraint to your UIImageView. Your images cell would look something like this:

class ImageTableViewCell: UITableViewCell {      @IBOutlet weak var customImageView: UIImageView!      internal var aspectConstraint : NSLayoutConstraint? {         didSet {             if oldValue != nil {                 customImageView.removeConstraint(oldValue!)             }             if aspectConstraint != nil {                 customImageView.addConstraint(aspectConstraint!)             }         }     }      override func prepareForReuse() {         super.prepareForReuse()         aspectConstraint = nil     }      func setCustomImage(image : UIImage) {          let aspect = image.size.width / image.size.height          let constraint = NSLayoutConstraint(item: customImageView, attribute: NSLayoutAttribute.width, relatedBy: NSLayoutRelation.equal, toItem: customImageView, attribute: NSLayoutAttribute.height, multiplier: aspect, constant: 0.0)         constraint.priority = 999          aspectConstraint = constraint          customImageView.image = image     } } 

You can check working example here DynamicTableWithImages

like image 67
sash Avatar answered Oct 02 '22 20:10

sash