I’ve been banging my head on this one. Perhaps someone can point me in the right direction.
I want to have a tablefield where the cells hold images. The images may be of different sizes, but I want the images to fill the width of the tableview and for the height of the row to be large enough to show the image in it’s original aspect ratio.
I have resized the tableviewcell so the height is correct, but all of my attempts to resize the imageview (by setting the frame and/or bounds) cause it to be too big within the tableviewcell.
If anyone knows of a working example, I’d like to see it!
You can use auto layout for this. Add constraints to the UIImageView so its top, bottom, leading and trailing edges are the same of the UITableViewCell. The cell’s width and the image’s dimensions will then determine the height of the cell.
The table view still needs to know that its cells are generating their own heights; you can do this in code.
117 in the above example doesn’t have to be an accurate value; the table view will use it as part of its layout calculations until the constraints take over. I think it does need to be greater than 0, though.
I’m assuming for this that the image occupies the entire cell and all of the cells in the table use autolayout.
It seems I was setting the setting the cell height to be the image height, rather than the height adjusted to match the image aspect ratio and tablefield width.
I still have an odd displacement of the leading edge, I guess I’ll work out where that is coming from…
Thanks for your assistance, although I was already doing those things, it was helpful to show I was on the right track.
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
... code removed here ...
switch thisContent.contentType {
case .Video: // This cell will just show a thumbnail image
let videoThumbCell = tableView.dequeueReusableCellWithIdentifier("videoCell")
let thumbnailPath = "\(thisContent.imagePath).png"
if let image = UIImage(named:thumbnailPath) {
tableView.beginUpdates()
let imageSize = image.size
let ratio = image.size.height / image.size.width
// Make the frame the right size to show the thumbnail
let cellFrame = CGRectMake(0, 0, tableView.contentSize.width, tableView.contentSize.width * ratio)
videoThumbCell?.frame = cellFrame
let imageView = videoThumbCell?.imageView // image view constraints pin all edges to the cell edges
imageView?.autoresizingMask = [.FlexibleWidth, .FlexibleHeight]
imageView?.translatesAutoresizingMaskIntoConstraints = true
imageView?.contentMode = .ScaleAspectFit
imageView?.image = image
// heightForRowIs is an array to store the row heights
heightForRowIs[ indexPath.row ] = cellFrame.height // newHeight
tableView.endUpdates()
}
return videoThumbCell!
The code above contains TWO significant problems that caused a bizarre behaviour that I couldn’t understand. The first problem is here:
let videoThumbCell = tableView.dequeueReusableCellWithIdentifier(“videoCell”)
It looks innocent enough, but videoThumbCell is referencing a class that inherits from UITableViewCell and extends it with a UIImageView element, plus some additional attributes, but here during dequeue I am dealing simply with a UITableViewCell.
It should have been:
let videoThumbCell = tableView.dequeueReusableCellWithIdentifier(“videoCell”) as! VideoTableViewCell
To access the correct class.
Later I have:
let imageView = videoThumbCell?.imageView
Now, given the first mistake, I reference an “imageView” attribute inside what should have been a UITableViewCell and later I assign an image to it.
The image appeared, but the imageView didn’t seem to be obeying it’s layout constraints, so everything seemed to work, but not properly!
I corrected the cell dequeue error and renamed the imageView to something else and now everything works as it should.
My advice:
Make sure that when you dequeue a custom cell with your own class, remember to cast it correctly so that you reference the correct object class.
Avoid using imageView as an attribute that references a UIImageView.