使用 AutoLayout 在自定义 UITableViewCell 中使用 Aspect Fill 的 UIImageView

UIImageView with Aspect Fill inside custom UITableViewCell using AutoLayout

我一直在努力拟合 UIImageView,它显示具有 Aspect Fill 的可变宽度和高度的图像。单元格高度不适应 UIImageView 的新高度并保持它的高度。

视图的层次结构是这样的

我在 XCode 自动布局中尝试了这些场景:

通过这些组合中的任何一个,我得到了这样的观点:

http://i.stack.imgur.com/Cw7hS.png

蓝线代表单元格边界(boundaries),绿线代表UIImageView边界(boundaries)。此示例中有四个单元格,第一个和第三个没有图像,第二个和第四个具有相同的图像(溢出具有 none 的图像)。

假设您有一个 UIImage,尺寸分别为 widthheight 的 768 x 592,高度始终保持相等,例如在上面的尺寸中旋转的设备(iPad),图像的width变为1024,height保持不变。

要保持​​图像的外观,您可以将其缩放到您想要的尺寸,例如,如果您知道出现的图像总是具有相同的尺寸,例如 1280x740,您可以设置UIImage.ScaleToFill 并按以下方式计算:

(widthOfTheImage / heightOfTheImage) * heightWhereYouWanToSet = widthYouHaveToSet

例如:

(1280 / 740) * 592 = 1024

这是我必须在 UIImage 中设置的 width 以在更改宽度时保持图像的比例。

我希望你明白我想对你说的地方。

我根据之前的两个答案拼凑了一个解决方案:

  • (见第 1 点)
  • (见第 2 点)

我想保留图像的 AspectRatio 而不管其 Height 而根据 UIImageView 的容器修复 Width图片。

解决方案包括:

  1. 添加新的AspectRatio约束

    let image = UIImage(ContentFromFile: "path/to/image")
    let aspect = image.size.width / image.size.height
    
    aspectConstraint = NSLayoutConstraint(item: cardMedia, attribute:  NSLayoutAttribute.Width, relatedBy: NSLayoutRelation.Equal, toItem: cardMedia, attribute: NSLayoutAttribute.Height, multiplier: aspect, constant: 0.0)
    

    添加此约束时,xCode 会抱怨新的 "redundant" 约束并尝试破坏它,使其变得无用,但仍会完全按照我想要的方式显示图像。这使我想到了第二个解决方案

    1. 将新约束的优先级降低到“999”似乎可以阻止 xcode 破坏它,并且它不再显示有关新约束的警告消息

      aspectConstraint?.priority = 999

不确定为什么 xCode 在 build/run 时自动添加 UIView-Encapsulated-Layout-HeightUIView-Encapsulated-Layout-Height;但是,我学会了如何尊重它并接受它:)

就把解决办法留在这里给大家看看。这适用于 iOS 8。我尝试使用 iOS7,但它的工作方式与您需要实现的不同 tableView:heightForRowAtIndexPath 根据包含的所有项目计算单元格的高度在其中并禁用设置:

tableView.rowHeight = UITableViewAutomaticDimension
tableView.estimatedRowHeight = 44.0