文章目录
- 1.瀑布流
- 1.1 demo地址
- 1.2 记得把部署的最低版本由8改成11,13甚至更高。不然编译会报错
- 2.动态计算图片和文字的高度
1.瀑布流
1.1 demo地址
CollectionViewWaterfallLayout - github
1.2 记得把部署的最低版本由8改成11,13甚至更高。不然编译会报错
2.动态计算图片和文字的高度
//可以正常使用
import UIKit
import SnapKit
class ConcernedVC: UICollectionViewController, UICollectionViewDelegateFlowLayout {
let cellReuseIdentifier = "WaterfallCell"
let itemsPerRow: CGFloat = 2
let sectionInsets = UIEdgeInsets(top: 10, left: 10, bottom: 10, right: 10)
let itemSpacing: CGFloat = 10 // Spacing between items in the same column
var columnHeights: [CGFloat] = [0, 0] // Heights of the two columns
let sampleData: [(image: UIImage, text: String)] = [
(UIImage(named: "img_about us_app")!, "Sample Text 1"),
(UIImage(named: "banner")!, "Sample Text 2adfahdfkajdfiahdofhadoifhaodhfaoihdfhasdifhaidhfapfdhiashf"),
(UIImage(named: "img_about us_app")!, "Sample Text 1"),
(UIImage(named: "banner")!, "Sample Text 2adfahdfkajdfiahdofhadoifhaodhfaoihdfhasdifhaidhfapfdhiashf"),
(UIImage(named: "img_about us_app")!, "Sample Text 1"),
(UIImage(named: "banner")!, "Sample Text 2adfahdfkajdfiahdofhadoifhaodhfaoihdfhasdifhaidhfapfdhiashf"),
(UIImage(named: "img_about us_app")!, "Sample Text 1"),
(UIImage(named: "img_about us_app")!, "Sample Text 1"),
// Add more sample data here
]
override func viewDidLoad() {
super.viewDidLoad()
// let layout = UICollectionViewFlowLayout() // Create a layout instance
// collectionView = UICollectionView(frame: .zero, collectionViewLayout: layout) // Initialize UICollectionView with the layout
collectionView.delegate = self
collectionView.dataSource = self
collectionView.register(WaterfallCell.self, forCellWithReuseIdentifier: cellReuseIdentifier)
collectionView.backgroundColor = .white
}
// MARK: UICollectionViewDataSource
override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return sampleData.count
}
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellReuseIdentifier, for: indexPath) as! WaterfallCell
let data = sampleData[indexPath.item]
cell.configure(with: data)
return cell
}
// MARK: UICollectionViewDelegateFlowLayout
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
let paddingSpace = sectionInsets.left * (itemsPerRow + 1)
let availableWidth = collectionView.frame.width - paddingSpace
let widthPerItem = availableWidth / itemsPerRow
let data = sampleData[indexPath.item]
let imageAspectRatio = data.image.size.width / data.image.size.height
let textHeight = data.text.height(withConstrainedWidth: widthPerItem - 16, font: UIFont.systemFont(ofSize: 14))
let imageHeight = min(200, widthPerItem / imageAspectRatio) // Limit image height
let totalHeight = imageHeight + textHeight + 16
return CGSize(width: widthPerItem, height: totalHeight)
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
return sectionInsets
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
return sectionInsets.left
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat {
return sectionInsets.left
}
}
class WaterfallCell: UICollectionViewCell {
let imageView = UIImageView()
let label = UILabel()
override init(frame: CGRect) {
super.init(frame: frame)
contentView.backgroundColor = .yellow
contentView.addSubview(imageView)
imageView.contentMode = .scaleAspectFill
imageView.clipsToBounds = true
contentView.addSubview(label)
label.numberOfLines = 2
label.font = UIFont.systemFont(ofSize: 14)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func configure(with data: (image: UIImage, text: String)) {
imageView.image = data.image
label.text = data.text
let imageAspectRatio = data.image.size.width / data.image.size.height
let imageHeight = frame.width / imageAspectRatio
imageView.frame = CGRect(x: 0, y: 0, width: frame.width, height: imageHeight)
label.frame = CGRect(x: 0, y: imageHeight + 8, width: frame.width, height: labelHeight)
}
private var labelHeight: CGFloat {
let labelWidth = frame.width - 16
return label.text?.height(withConstrainedWidth: labelWidth, font: UIFont.systemFont(ofSize: 14)) ?? 0
}
}
extension String {
func height(withConstrainedWidth width: CGFloat, font: UIFont) -> CGFloat {
let constraintRect = CGSize(width: width, height: .greatestFiniteMagnitude)
let boundingBox = self.boundingRect(with: constraintRect, options: .usesLineFragmentOrigin, attributes: [NSAttributedString.Key.font: font], context: nil)
return ceil(boundingBox.height)
}
}
//使用
let layout = UICollectionViewFlowLayout()
layout.scrollDirection = .vertical
let vc = ConcernedVC(collectionViewLayout: layout)