Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
269 views
in Technique[技术] by (71.8m points)

ios - Dynamic UIImageView Size Within UITableView

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: image Image 2

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...