UITableView中的dynamicUIImageView大小

我想用自定义的TableViewCell实现一个显示图像的TableView。

为了简单起见,我只需使用autolayout将一个UIImageView放在tableviewcell中(如下图所示)。 在这里输入图像说明

我想要的是在UIImageView内显示图像,但这些图像尺寸可以是任何东西,并不一致(肖像,风景,广场)…

因此,我正在寻找显示具有固定宽度(设备的宽度)和尊重图像比例的dynamic高度的图像。 我想要这样的东西: 在这里输入图像说明

我不幸没有达到这个结果。

下面是我如何实现它(我使用Haneke从URL中加载图像 – 存储在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 } 

我的dynamic高度的计算是正确的(我打印了它)。 我已经尝试了两种方法(在代码中描述),但没有一个工作:

  1. 设置UIImageView的Height Autolayout约束
  2. 修改UIImageView的框架

在这里查看方法1和2的结果: 图片图片2

在故事板中为您的UIImageView添加尾随,前导,底部和顶部约束。 加载图像之后,所有你需要做的就是添加一个方面约束到你的UIImageView 。 你的图片单元格看起来像这样:

 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 } } 

你可以在这里查看工作示例DynamicTableWithImages

如果你想让UIImageView告诉UITableView需要多高,那么你需要configuration表视图来启用自动行计算。 您可以通过将estimatedRowHeight设置为固定正值并将rowHeight设置为UIViewAutomaticDimension来实现此目的。 这是第一部分。

现在,您需要configurationUIImageView以基于表视图需要的宽度和图像的高宽比来请求高度。 这将是第二部分。

首先,将contentMode设置为.AspectFit。 这将导致视图根据所需的任何尺寸调整图像的外观。 但是,这仍然不会导致自动布局请求所需的高度。 相反,它会请求intrinsicContentSize的高度,这可能与调整后的图像大不相同。 所以,第二,为UIImageView添加一个约束,forms为width = height * multiplier ,其中乘数基于图像本身的宽高比。

现在表视图需要正确的宽度,contentMode机制将确保图像正确resize而不失真,并且纵横比约束将确保图像视图通过自动布局需要正确的高度。

这工作。 不利的一面是,每次将新图像分配给图像视图时,您都需要更新宽高比约束,如果图像视图位于正被重用的单元中,则可能会非常频繁。

另一种方法是仅添加高度约束,并将其更新到包含图像视图的视图的layoutSubviews中。 这具有更好的性能,但更糟糕的代码模块化。

从imageView中删除高度约束。 select以“方面”开头的图像视图的contentMode,例如:方面填充或方面适合(因为它符合您的要求)。

注意 :您还需要设置行的高度,以便imageView适合它。 使用

 heightForRowAtIndexPath 

设置自定义行高。

在这里输入图像说明

在将图像加载到tableView时,每个图像可以具有不同的纵横比。 通过使用SDWebImage,我们可以从url获取图像,

  testImageView.sd_setImage(with: url, placeholderImage: nil, options: [], completed: { (downloadedImage, error, cache, url) in print(downloadedImage?.size.width)//prints width of image print(downloadedImage?.size.height)//prints height of image }) 

UITableViewCellUITableViewCell的约束条件设置为999,优先级为topbottomleadingtrailingfixed height constraint ,并根据图像改变height-constraint-constant

  var cellFrame = cell.frame.size cellFrame.height = cellFrame.height - 15 cellFrame.width = cellFrame.width - 15 cell.feedImageView.sd_setImage(with: url, placeholderImage: nil, options: [], completed: { (theImage, error, cache, url) in cell.feedImageHeightConstraint.constant = self.getAspectRatioAccordingToiPhones(cellImageFrame: cellFrame,downloadedImage: theImage!) }) 

计算单元格框架,并find相应的高度。

  func getAspectRatioAccordingToiPhones(cellImageFrame:CGSize,downloadedImage: UIImage)->CGFloat { let widthOffset = downloadedImage.size.width - cellImageFrame.width let widthOffsetPercentage = (widthOffset*100)/downloadedImage.size.width let heightOffset = (widthOffsetPercentage * downloadedImage.size.height)/100 let effectiveHeight = downloadedImage.size.height - heightOffset return(effectiveHeight) } 

在Github上的例子