提问人:robinyapockets 提问时间:8/2/2023 更新时间:8/3/2023 访问量:26
使用 Autolayout 和 UICollectionViewCompositionalLayout 的动态集合视图单元格中的 UIImage 大小调整
UIImage Sizing in Dynamic Collection View Cell with Autolayout and UICollectionViewCompositionalLayout
问:
上下文:我有一个集合视图,其动态单元格高度由其单元格的内容定义。单元格的内容:UIView、UILabel 和 UIImage(图像和标签垂直放置)。
问题:当我将图像contentMode设置为scaleAspectFill时,自动布局似乎可以正常工作并相应地调整单元格的大小。但是,这会裁剪图像的侧面。当我将 contentMode 设置为 scaleAspectFit 时,它会在水平方向上正确调整图像大小,但保持以前的高度。
附上结果的图像。感谢您的任何提示和支持!
集合视图布局代码:
func createLayout() -> UICollectionViewLayout {
let _: CGFloat = (self.view.frame.width*1.33) + 50
let estimatedHeight = CGFloat(100)
let layoutSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0),
heightDimension: .estimated(estimatedHeight))
let item = NSCollectionLayoutItem(layoutSize: layoutSize)
let group = NSCollectionLayoutGroup.horizontal(layoutSize: layoutSize,
repeatingSubitem: item,
count: 1)
let section = NSCollectionLayoutSection(group: group)
section.contentInsets = NSDirectionalEdgeInsets(top: 10, leading: 10, bottom: 10, trailing: 10)
section.interGroupSpacing = 10
let layout = UICollectionViewCompositionalLayout(section: section)
return layout
}
对于小区注册:
let newCell = UICollectionView.CellRegistration<CustomCell, Asset> {(cell, indexPath, item) in
let image = UIImage(named: "test")
cell.label.text = "No comments"
cell.imageView.image = image
}
对于自定义单元格:
class CustomGroupItemCell: UICollectionViewCell {
let container = UIView()
let imageView = UIImageView()
let label = UILabel()
override init(frame: CGRect) {
super.init(frame: frame)
configure()
}
required init?(coder: NSCoder) {
fatalError("not implemnted")
}
func configure() {
container.translatesAutoresizingMaskIntoConstraints = false
imageView.translatesAutoresizingMaskIntoConstraints = false
label.translatesAutoresizingMaskIntoConstraints = false
label.adjustsFontForContentSizeCategory = true
label.numberOfLines = 0
label.font = UIFont.systemFont(ofSize: 17, weight: .semibold)
label.textColor = .label
container.backgroundColor = .secondarySystemFill
container.layer.cornerRadius = 12
imageView.layer.cornerRadius = 5
imageView.contentMode = .scaleAspectFill
imageView.layer.masksToBounds = true
contentView.addSubview(container)
contentView.addSubview(label)
contentView.addSubview(imageView)
let views = [ "label": label, "container": container, "image": imageView]
var constraints = [NSLayoutConstraint]()
// Horizontal
constraints.append(contentsOf: NSLayoutConstraint.constraints(
withVisualFormat: "H:|[container]|", options: [], metrics: nil, views: views))
constraints.append(contentsOf: NSLayoutConstraint.constraints(
withVisualFormat: "H:|-20-[image]-20-|", options: [], metrics: nil, views: views))
constraints.append(contentsOf: NSLayoutConstraint.constraints(
withVisualFormat: "H:|-20-[label]-20-|", options: [], metrics: nil, views: views))
// Vertical
constraints.append(contentsOf: NSLayoutConstraint.constraints(
withVisualFormat: "V:|[container]|",
options: [], metrics: nil, views: views))
constraints.append(contentsOf: NSLayoutConstraint.constraints(
withVisualFormat: "V:|-20-[image]-20-[label]-24-|",
options: [], metrics: nil, views: views))
NSLayoutConstraint.activate(constraints)
}
}
答:
0赞
matt
8/3/2023
#1
你不能以任何自动魔法的方式做到这一点。当图像准备好放置在单元格中时,您需要读取其大小并相应地调整图像视图的大小约束。
例如,在我的应用程序中,图像视图和单元格宽度是固定的。当图像到达时,我计算出它的纵横比,并将该值设置为图像视图纵横比约束的乘数,从而设置高度以适合图像。
评论
0赞
robinyapockets
8/3/2023
谢谢@matt!我假设使用 iOS 15 的 UICollectionViewCompositionalLayout 可以在不使用 Autolayout 计算比率的情况下完成。对我来说,这感觉有点“骇人听闻”。将尝试计算比率和调整高度。
0赞
robinyapockets
8/3/2023
@matt的答案奏效了!对于任何感兴趣的人,这里有代码: func adjustImageHeight(for image: UIImage){ let ratio = image.size.height/image.size.width NSLayoutConstraint.activate([ imageView.heightAnchor.constraint(equalTo: contentView.widthAnchor, multiplier: ratio, constant: -40) ]) } var image: UIImage?{ didSet{ adjustImageHeight(for: image!) } }
评论