swift - 根据图像制作具有 UIImageView 高度的 UICollectionViewCells
问题描述
我想UICollectionView
用单元格制作屏幕的宽度,但高度基于UIImageView
内部的纵横比。
在我当前的实现中,所有UICollectionViewCell
实例都是正方形,这不是我想要的。
我想以某种方式使用自动布局来使图像的大小成为屏幕的宽度,但相关的高度取决于所用图像的纵横比。
一切都是在代码中以编程方式完成的。
我的代码:
class ViewController: UIViewController {
var data = ["1","2","3","4","5","6","7","8","1","2","3","4","5","6","7","8"]
var collectionView: UICollectionView!
override func viewDidLoad() {
super.viewDidLoad()
self.collectionView.dataSource = self
self.collectionView.delegate = self
self.collectionView.register(SubclassedCollectionViewCell.self, forCellWithReuseIdentifier: "cell")
self.collectionView.alwaysBounceVertical = true
self.collectionView.backgroundColor = .white
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
}
override func loadView() {
let layout: UICollectionViewFlowLayout = UICollectionViewFlowLayout()
layout.itemSize = CGSize(width: UIScreen.main.bounds.size.width - 20, height: UIScreen.main.bounds.size.width / 1)
layout.scrollDirection = .vertical
collectionView = UICollectionView(frame: .zero, collectionViewLayout: layout)
self.view = collectionView
}
}
extension ViewController: UICollectionViewDataSource {
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
data.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
if let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as? SubclassedCollectionViewCell {
let data = self.data[indexPath.item]
cell.setupCell(image: data)
return cell
}
fatalError("Could not dequeue cell")
}
}
与细胞
class SubclassedCollectionViewCell: UICollectionViewCell {
var hotelImageView: UIImageView = {
var hotelView = UIImageView()
hotelView.contentMode = .scaleAspectFill
hotelView.clipsToBounds = true
return hotelView
}()
override init(frame: CGRect) {
super.init(frame: frame)
addSubview(hotelImageView)
hotelImageView.translatesAutoresizingMaskIntoConstraints = false
hotelImageView.topAnchor.constraint(equalTo: topAnchor).isActive = true
hotelImageView.leftAnchor.constraint(equalTo: leftAnchor).isActive = true
hotelImageView.rightAnchor.constraint(equalTo: rightAnchor).isActive = true
hotelImageView.bottomAnchor.constraint(equalTo: bottomAnchor).isActive = true
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func setupCell(image: String) {
if let image : UIImage = UIImage(named: image) {
hotelImageView.image = image
}
}
}
解决方案
首先,根据宽度计算比率并乘以集合视图宽度,您可以获得基于宽度的新高度。
最终代码:从 loadview 函数中删除 itemSize。并在 sizeForItemAt 方法中计算高度和返回项目大小。
加载视图
override func loadView() {
let layout: UICollectionViewFlowLayout = UICollectionViewFlowLayout()
// layout.itemSize = CGSize(width: UIScreen.main.bounds.size.width - 20, height: UIScreen.main.bounds.size.width / 1) <-- Remove this
layout.scrollDirection = .vertical
collectionView = UICollectionView(frame: .zero, collectionViewLayout: layout)
self.view = collectionView
}
UICollectionViewDelegateFlowLayout
extension ViewController: UICollectionViewDataSource, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout {
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
data.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
if let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as? SubclassedCollectionViewCell {
let data = self.data[indexPath.item]
cell.setupCell(image: data)
return cell
}
fatalError("Could not dequeue cell")
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
guard let iamgeData = UIImage(named: self.data[indexPath.item]) else {
return .zero
}
let width = collectionView.bounds.width
let heightOnWidthRatio = iamgeData.size.height / iamgeData.size.width
let height = width * heightOnWidthRatio
return CGSize(width: width, height: height)
}
}
推荐阅读
- javascript - 根据命令输入从目录中抓取随机图像
- hadoop - 将 Hadoop 集群从 Big Insights 迁移到 Cloudera
- database - 如何在 PostgreSQL 中显示货币价值
- angularjs - 使用 adaljs 的 Angularjs 页面一直在寻找令牌
- javascript - 如果在没有更改事件的情况下选中子单选按钮,如何显示父数据选项卡值?
- javascript - 用空格分隔的字符串到javascript中的对象
- c++ - QWidget::paintEngine:不应再在 QTreeWidget 派生类中调用
- javascript - 柴期望 - 期望(browser.getTitle())错误 - browser.getTitle 不是函数
- r - 在 R 中绘制多个图
- ios - 表达式类型'@Ivalue String?' 在没有更多上下文的情况下是模棱两可的 错误