我正在尝试获取一个包含多个UIImageViews
的自定义照片容器,以适合我的tableview单元格。视图包含可变数量的图像(1~9),其高度将相应地从1x变为3x imageHeight。
我使用AutoLayout定义了tableview和自定义UIView里面的顶部/底部/前导/尾部边距,并且为了启用自定义单元格,我已经设置了
tableView.estimatedRowHeight = X
tableView.rowHeight = UITableViewAutomaticDimension
我用
初始化这些单元格tableView.register(nib: forCellReuseIdentifier:)
并且在tableView(_ tableView: cellForRowAt:)
方法中,我使用:
let cell = tableView.dequeueReusableCell(
withIdentifier: "test9cell",
for: indexPath) as! SocialFeedTableViewCell
cell.photoContainer.setup(with: urls)
cell.photoContainer.loadImages()
return cell
其中setup()
使用URL
func setup(with urls: [URL]) {
self.imageUrls = urls
for i in 0 ..< urls.count {
let imageView = UIImageView(frame: CGRect.zero)
self.addSubview(imageView)
self.imageViews.append(imageView)
}
self.setNeedsLayout()
}
func loadImages() {
self.imageViews.forEach { imageView in
imageView.frame = // Calculate position for each subview
imageView.sd_setImage(...) // Load web image asynchronously
}
}
为视图定义intrinsicContentSize:
override var intrinsicContentSize {
let frameWidth = self.frame.size.width
var frameHeight: CGFloat
switch self.imageUrls.count { // range from 1...9
case 1...3:
frameHeight = frameWidth / 3
case 4...6:
frameHeight = frameWidth / 3 * 2
default:
frameHeight = frameWidth
return CGSize(frameWidth, frameHeight)
}
override func layoutSubviews() {
super.layoutSubviews()
self.imageViews.forEach { imageView in
imageView.frame = // Calculate position for each subview
}
}
这里的问题是:在我设置了初始的intrinsicContentSize之后,容器的帧大小在layoutSubviews()之后发生了变化。虽然到那时我可以正确定位imageView子视图,但不再更改单元格高度。
希望我不会让这个问题更加混乱。有人可以指出在修改其UIView子视图的内容后如何调整单元格高度?谢谢!
答案 0 :(得分:0)
这里有一些事情会导致动态大小的单元格出现问题。
现在最后一点更复杂了。
动态UITableViewCell根据其中内容的自动布局规则计算其高度。你必须有足够的约束从你的内容到UITableViewCell的contentView属性(到所有边缘),它给单元格足够的信息来放置每个项目,计算它的整体高度和宽度,因此它能够计算新的高度。
对于动态大小的单元格,仅使用一个图像并不算太糟糕。但是在单元格最初渲染后没有任何规则动态放置多个项目将不起作用。
您需要决定如何在细胞中布置这些图像。完成后,您可以在添加图像视图时添加所需的约束。我个人只会在收到每张图片后添加图片视图。
以前当我这样做时,我已经缓存了图像并重新加载了单元格,以便图像可以在渲染时放置在单元格中,允许tableview单元格根据图像尺寸计算其高度和约束。
您可能还想考虑使用集合视图或将图像合并到一个图像中并在单元格中使用它。如果您具有对图像的访问权限,则可以在运行时或服务器端在设备上执行此操作。