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高度的计算是正确的(我打印了它)。 我已经尝试了两种方法(在代码中描述),但没有一个工作:
- 设置UIImageView的Height Autolayout约束
- 修改UIImageView的框架
在这里查看方法1和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 })
在UITableViewCell
将UITableViewCell
的约束条件设置为999,优先级为top
, bottom
, leading
, trailing
, fixed 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上的例子
- 自动布局约束更改不animation
- 当我将UIPanGestureRecognizer和自动布局结合在一起时,我的UIViews变得糟糕透顶
- UICollectionViewCell自动布局
- 如何在自动布局的横向模式下设置水平文本字段?
- 我有一个UILabel自动布局定位在屏幕上,但是当我隐藏导航栏,它会导致标签“抽搐”第二个
- 带有AutoLayout的UICollectionView Cell + UiLabel
- UIScrollView自动布局与“页脚”固定到屏幕底部
- 使用“自动布局”,如何使同一“行”上的两个标签在宽度上dynamic变化(根据每个标签的宽度进行调整)?
- 如何将3个UIButtonalignment到UITableCellView的中心?