我正在尝试将合成布局与UICollectionView一起使用,其中每个单元格都包含一个具有动态纵横比的图像。我正在对单元格使用自动布局,但无法正确地自动调整单元格的大小。
指定单元格布局/约束的正确方法是什么,以便它们具有基于图像纵横比的正确高度?
在下面的代码中,图像本身的大小是正确的,但是包含它们的单元格没有正确的高度(它们只是使用估计的高度,而不是根据包含的图像动态调整)。
(我知道使用UICollectionViewFlowLayout相对简单,但我正在尝试学习组合布局,使用此方法还不能弄清楚)
下面是我在代码中设置的内容:
为了简化这篇文章,我使用了一个基本的组合布局,其中包含1个组和1个项,并使用heightDimension: .estimated(300)
作为占位符
let layout = UICollectionViewCompositionalLayout { (sectionIndex, layoutEnvironment) -> NSCollectionLayoutSection? in
let item = NSCollectionLayoutItem(layoutSize: NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0), heightDimension: .estimated(300)))
let group = NSCollectionLayoutGroup.vertical(layoutSize: NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0), heightDimension: .estimated(300)), subitem: item, count: 1)
let section = NSCollectionLayoutSection(group: group)
return section
}
collectionView.setCollectionViewLayout(layout, animated: false)
下面是该单元格的代码:
// during cellForItemAt, I call
// cell.setImage(url: [url from API], size: [dynamic value from API])
class ImageCell: UICollectionViewCell {
static let ImageCellIdentifier = String(describing: ImageCell.self)
var aspectRatioConstraint: NSLayoutConstraint?
private let imageView: UIImageView = {
let imageView = UIImageView()
imageView.translatesAutoresizingMaskIntoConstraints = false
imageView.contentMode = .scaleAspectFill
return imageView
}()
func setImage(url: URL, size: CGSize) {
let aspectRatio = size.width / size.height
if let aspectRatioConstraint = aspectRatioConstraint {
imageView.removeConstraint(aspectRatioConstraint)
}
// set the image height constraint based on its aspect ratio
// anchor it to contentView.widthAnchor
aspectRatioConstraint = imageView.heightAnchor.constraint(equalTo: contentView.widthAnchor, multiplier: aspectRatio)
NSLayoutConstraint.activate([
aspectRatioConstraint!,
])
imageView.sd_setImage(with: url)
contentView.layoutIfNeeded()
}
override init(frame: CGRect) {
super.init(frame: frame)
contentView.addSubview(imageView)
NSLayoutConstraint.activate([
imageView.topAnchor.constraint(equalTo: contentView.topAnchor),
imageView.widthAnchor.constraint(equalTo: contentView.widthAnchor),
])
}
}
1条答案
按热度按时间jgovgodb1#
感谢@DonMag的评论,答案是每个项目创建一个部分,并相应地指定每个项目部分的布局:
假设
images
填充有动态图像列表(例如,来自API)组合布局的设置如下所示--重要的部分是
... heightDimension: .fractionalWidth(aspectRatio)
谢谢@DonMag!