ios swift5 collectionView 瀑布流(两列)

文章目录

  • 1.瀑布流
    • [1.1 demo地址](#1.1 demo地址)
    • [1.2 记得把部署的最低版本由8改成11,13甚至更高。不然编译会报错](#1.2 记得把部署的最低版本由8改成11,13甚至更高。不然编译会报错)
  • 2.动态计算图片和文字的高度

1.瀑布流

1.1 demo地址

CollectionViewWaterfallLayout - github

1.2 记得把部署的最低版本由8改成11,13甚至更高。不然编译会报错

2.动态计算图片和文字的高度

swift 复制代码
//可以正常使用
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)
相关推荐
for_ever_love__10 小时前
UI学习:UICollectionView瀑布流
学习·ui·ios·objective-c·cocoa
大熊猫侯佩13 小时前
WWDC26 全网首发:SwiftUI 8 “可重排序“操作符深度解析
ios·swiftui·swift
邓小乐15 小时前
Workaround: Xcode27 下载iOS 27.0 Simulator
ios·xcode
韩曙亮15 小时前
【Flutter】Flutter 中的 Android / iOS 特殊配置 ① ( 网络权限配置 | HTTP 明文传输配置 | 应用名称配置 )
android·网络·flutter·http·ios·网络权限
人月神话-Lee17 小时前
【图像处理】颜色空间——RGB之外的世界
图像处理·人工智能·ios·ai编程·swift·rgb·颜色空间
CocoaKier18 小时前
苹果后台年龄分级填写错误,可能导致审核被拒!
ios·apple
月诸清酒18 小时前
Codex 现在能在浏览器里跑 iOS 模拟器了
ios
武子康19 小时前
调查研究-159 Apple WWDC 2026 定档 6/8-12:Siri 与 AI 升级,可能是苹果最关键的一次
人工智能·深度学习·ios·ai·chatgpt·apple·wwdc
2601_9611940220 小时前
27考研资料|百度网盘|夸克网盘
android·xml·考研·ios·iphone·xcode·webview