iOS Swift 如何伪造一个UICollectionView的 Footer View

前言:

最近遇到一个磨人的需求。

背景:我们的首页用的是 UICollectionView。在这个collectionview的底部,放一个FooterView,用来写点提示信息。
要求:
1、如果collectionview的内容比较少(也就是说:collectionView.frame.height > collectionView.contentSize.height),那么这个FooterView就直接放到collectionview的底部。
2、如果collectionview的内容比较多(也就是说:collectionView.frame.height < collectionView.contentSize.height),那么这个FooterView就需要跟随collectionview滚动。

如果是在UITableView上,我们可以这么干:

let tableView = UITableView()
tableView.tableFooterView = UIView()

但是在 UICollectionView 上,我没有点出来这个footerview的属性。这就很尴尬了。我去网上搜了一下,发现大家用的都是SectionHeader的办法。那这就有个问题了,SectionFooter 也是能写的,但是在collectionview内容比较少的时候,这个SectionFooter并不会放在collectionview的最底部,会放在屏幕中间。我家UI设计员肯定不会提意见

然后,我想了很久。决定伪造一下FooterView。

Swift
代码地址:https://github.com/gityuency/Autolayout
示例代码类名 【FakeCollectionViewController】

示例效果

iOS Swift 如何伪造一个UICollectionView的 Footer View_第1张图片
假的.gif
思路:

第一步:使用UIEdgeInsets来给collectionview底部设置一个缩进。
第二步:给collectionview添加一个视图,用来做FooterView。
第三步:在代理方法里面拿到collectionview的内容高度,给这个FooterView设置一下Frame。

代码:

import UIKit

class FakeCollectionViewController: UIViewController {
    
    @IBOutlet weak var collectionView: UICollectionView!
    
    /// 复用 ID
    let rid = "rid"
    
    /// 单元格个数
    var cellcount = 10
    
    /// FooterView的高度
    let FooterHeight: CGFloat = 60
    
    /// 记录 collectionview 的内容高度
    var contentHeight: CGFloat = 0
    
    /// 放在底部的View
    lazy var footerView: UIButton = {
        let b = UIButton()
        b.setTitle("点击 FooterView", for: UIControl.State.normal)
        b.backgroundColor = UIColor.brown
        b.addTarget(self, action: #selector(click), for: .touchUpInside)
        return b
    }()
    
    @objc func click() {
        print("测试是否可以点击")
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        if #available(iOS 11.0, *) {
            collectionView.contentInsetAdjustmentBehavior = .never
        } else {
            automaticallyAdjustsScrollViewInsets = false
        }
        
        collectionView.delegate = self
        collectionView.dataSource = self
        collectionView.register(UICollectionViewCell.self, forCellWithReuseIdentifier: rid)
        collectionView.addSubview(footerView)
        collectionView.contentInset = UIEdgeInsets(top: 0, left: 0, bottom: FooterHeight, right: 0)
        // contentSize 是不包括 EdgeInsets的
    }
}


extension FakeCollectionViewController: UICollectionViewDataSource, UICollectionViewDelegate {
    
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return cellcount
    }
    
    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: rid, for: indexPath)
        cell.backgroundColor = UIColor.orange
        return cell
    }
    
    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
        
        cellcount += 10
        collectionView.reloadData()
    }
    
    // 在这个方法里面可以拿到视图的内容高度
    func collectionView(_ collectionView: UICollectionView, willDisplay cell: UICollectionViewCell, forItemAt indexPath: IndexPath) {
        
        if contentHeight == collectionView.contentSize.height { //如果内容高度没有变化,就不需要设置footer的位置
            return
        }
        
        contentHeight = collectionView.contentSize.height
        
        if collectionView.frame.height > collectionView.contentSize.height + FooterHeight { //当视图的高度 比 (内容高度 + Footer高度) 大的时候
            
            DispatchQueue.main.async {
                print("直接放到collectionview的底部: \(collectionView.contentSize.height)")
                let w = collectionView.bounds.width
                let y = collectionView.frame.height - self.FooterHeight
                self.footerView.frame = CGRect(x: 0, y: y, width: w, height: self.FooterHeight)
            }
            
        } else {
            
            DispatchQueue.main.async {
                print("根据内容高度调整到底部: \(collectionView.contentSize.height)")
                let w = collectionView.bounds.width
                let y = collectionView.contentSize.height
                self.footerView.frame = CGRect(x: 0, y: y, width: w, height: self.FooterHeight)
            }
        }
    }
}

//if (cellcount - 1) == collectionView.indexPathsForVisibleItems.last?.row { // 这里表示要显示最后一个cell
//}

结语:

今天八月二十一号了。我们Team换了座位。也算的上是个惬意的位置,右边是很大飘窗,窗外是xx办事中心。好像是个欧式风格的建筑?想想两年前我坐在一个柱子旁边,有种被遗弃的感觉。


iOS Swift 如何伪造一个UICollectionView的 Footer View_第2张图片
无题

你可能感兴趣的:(iOS Swift 如何伪造一个UICollectionView的 Footer View)