iOS UI 之 UICollectionView

769 阅读2分钟

Overview

CollectionView是用来管理一组有序的数据并通过自定义的布局来展示

collection view 从 data source object 中得到数据,这样它会有一个dataSource的属性。你可以使用UICollectionViewDiffableDataSource 来简单并有效的管理collection view中的数据和用户的交互;你也可以使用UICollectionViewDataSource来管理自定义的data source。

collection view 中的数据被整理成单个item,每个item是你想展示的最小单元。collection view 使用cell来展示当个item,这里要用到UICollectionViewCell 类。

Layouts

一个layout的对象定义来collection view中内容的视觉上的安排。可以使用 UICollectionViewLayout来定义layout对象。collection view中可以使用collectionViewLayout属性来设置对象。设置这个属性能够立即的改变整个collection View的布局,不需要动画。如果你想加入动画效果可以调用setCollectionViewLayout(_:animated:completion:)方法。

Cells and Supplementary Views

当collection view第一次加载它的内容时,会告诉data source去提供一个视图对每一个需要展示的cell可见。collection view维护一个队列来标记data source是不是reuse的。

这里有两种方法来对视图进行出队操作。

  • dequeueReusableCell(withReuseIdentifier:for:):得到一个collection view 中的一个cell
  • dequeueReusableSupplementaryView(ofKind:withReuseIdentifier:for:):得到一个layout对象需要的supplementary view

在调用这些方法钱,你必须告诉collection view怎么去创建对应的视图。为了得到这个,你必须注册一个类或者一个nib文件。例如,当注册cell时,你可以使用register(_:forCellWithReuseIdentifier:)来注册一个类,或者使用register(_:forCellWithReuseIdentifier:) 来注册一个nib文件。在注册过程中,你必须指明reuse identifier,这个reuse identifier用来用来指明视图的目的。当视图出队时也会用到这个一样的字符串。

Data Prefetching

Reordering Items Interactively

Interface Builder Attributes

代码展示

首先自定义cell

class MyCollectionCell: UICollectionViewCell {
    override init(frame: CGRect) {
        super.init(frame: frame)
        self.backgroundColor = UIColor.red
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}

在ViewController中定义collectionView,并加载在view上

class ViewController: UIViewController {
   
    lazy var collectionView: UICollectionView = {
        let layout = UICollectionViewFlowLayout.init()
        let itemW = (self.view.bounds.width - 30) / 2
        layout.itemSize = CGSize.init(width: itemW, height: itemW + 40)
        layout.minimumLineSpacing = 5
        layout.minimumInteritemSpacing = 10
        layout.sectionInset = UIEdgeInsets.init(top: 10, left: 10, bottom: 10, right: 10)
        
        let collectionView = UICollectionView.init(frame: self.view.bounds,collectionViewLayout: layout)
        collectionView.backgroundColor = UIColor.blue
        collectionView.dataSource = self
        collectionView.delegate = self
        collectionView.register(MyCollectionCell.self, forCellWithReuseIdentifier: "UICollectionReusableView")
        
        return collectionView
    }()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        self.view.addSubview(collectionView)
    }
}

最后扩展协议

extension ViewController:UICollectionViewDataSource, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout{
    
    func numberOfSections(in collectionView: UICollectionView) -> Int {
        return 1
    }
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return 20
    }
    
    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "UICollectionReusableView", for: indexPath) as! MyCollectionCell
        cell.layer.cornerRadius = 5
        cell.layer.masksToBounds = true
        return cell
    }
}

效果

image.png