美文网首页
iOS Swift 如何伪造一个UICollectionView

iOS Swift 如何伪造一个UICollectionView

作者: Yuency | 来源:发表于2019-08-21 10:47 被阅读0次

    前言:

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

    背景:我们的首页用的是 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】

    示例效果

    假的.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

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