美文网首页
Swift之UICollectionView瀑布流

Swift之UICollectionView瀑布流

作者: 黄成瑞 | 来源:发表于2020-11-19 13:51 被阅读0次

    相信大家对UICollectionView的使用都不陌生了,这里我要简单说下瀑布流的功能实现,希望有助于大家对瀑布流的实现逻辑有所加深理解,先上效果图

    效果图
    效果图
    WaterFallLayout 类
    import Foundation
    import UIKit
    
    class WaterFallLayout: UICollectionViewFlowLayout {
        // item个数
        let itemCount: Int
        // items的布局信息
        var attributeArray: Array<UICollectionViewLayoutAttributes>?
        
        // 实现必要的构造方法
        required init?(coder: NSCoder) {
            itemCount = 0
            super.init(coder: coder)
        }
        
        // 自定义一个初始化构造方法
        init(itemCount: Int) {
            self.itemCount = itemCount
            super.init()
        }
        
        // 准备方法
        override func prepare() {
            // 调用父类的准备方法
            super.prepare()
            // 设置为竖直布局
            self.scrollDirection = .vertical
            // 初始化数组
            attributeArray = Array<UICollectionViewLayoutAttributes>()
            // 先计算每个item的宽度,默认为两列布局
            let WIDTH = (UIScreen.main.bounds.size.width - self.minimumInteritemSpacing) / 2
            // 定义一个元组表示每一列的动态高度
            var queueHeight:(one: Int, two: Int) = (0,0)
            // 进行循环设置
            for index in 0..<self.itemCount {
                // 设置indexPath,默认一个分区
                let indexPath = IndexPath(item: index, section: 0)
                // 创建布局属性类
                let attris = UICollectionViewLayoutAttributes(forCellWith: indexPath)
                // 随机一个高度在80到90之间的值
                let height: Int = Int(arc4random() % 110 + 80)
                // 哪列高度小就把它放那列下面
                // 标记那一列
                var queue = 0
                if queueHeight.one <= queueHeight.two {
                    queueHeight.one += (height + Int(self.minimumInteritemSpacing))
                    queue = 0
                } else {
                    queueHeight.two += (height+Int(self.minimumInteritemSpacing))
                    queue = 1
                }
                // 设置item的位置
                let tmpH = queue == 0 ? queueHeight.one-height : queueHeight.two-height
                attris.frame = CGRect(x: (self.minimumInteritemSpacing+WIDTH)*CGFloat(queue), y: CGFloat(tmpH), width: WIDTH, height: CGFloat(height))
                // 添加到数组中
                attributeArray?.append(attris)
            }
            // 以最大一列的高度计算每个item高度的中间值,这样就可以保证滑动范围的正确
            if queueHeight.one <= queueHeight.two {
                self.itemSize = CGSize(width: WIDTH, height: CGFloat(queueHeight.two*2/self.itemCount)-self.minimumLineSpacing)
            } else {
                self.itemSize = CGSize(width: WIDTH, height: CGFloat(queueHeight.one*2/self.itemCount)-self.minimumLineSpacing)
            }
        }
        // 将设置好存放每个item的布局信息返回
        override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
            return attributeArray
        }
    }
    
    ViewController 类
    import UIKit
    
    class ViewController: UIViewController, UICollisionBehaviorDelegate, UICollectionViewDataSource, UICollectionViewDelegate {
        
        override func viewDidLoad() {
            super.viewDidLoad()
            // Do any additional setup after loading the view.
            
            let layout = WaterFallLayout(itemCount: 30)
            let collectionView = UICollectionView(frame: self.view.frame, collectionViewLayout: layout)
            collectionView.delegate = self
            collectionView.dataSource = self
            collectionView.register(NSClassFromString("UICollectionViewCell"), forCellWithReuseIdentifier: "itemID")
            self.view.addSubview(collectionView)
            
        }
    
        func numberOfSections(in collectionView: UICollectionView) -> Int {
            return 1
        }
        
        func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
            return 30
        }
        
        func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
            let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "itemID", for: indexPath)
            cell.backgroundColor = UIColor(red: CGFloat(arc4random()%255)/255, green: CGFloat(arc4random()%255)/255, blue: CGFloat(arc4random()%255)/255, alpha: 1)
            return cell
        }
        
        func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
            print("点击了第\(indexPath.row)个item")
        }
    
    }
    

    参考文章:
    swift4-UICollectionView(实现瀑布流)

    相关文章

      网友评论

          本文标题:Swift之UICollectionView瀑布流

          本文链接:https://www.haomeiwen.com/subject/rcakiktx.html