import UIKit import DataSources class ViewController: UIViewController, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout { var collectionView: UICollectionView = { let layout = UICollectionViewFlowLayout() layout.sectionInset = .zero layout.minimumLineSpacing = 0 layout.minimumInteritemSpacing = 0 let collectionView = UICollectionView(frame: .zero, collectionViewLayout: layout) collectionView.register(Cell.self, forCellWithReuseIdentifier: "Cell") collectionView.register(Header.self, forSupplementaryViewOfKind: UICollectionElementKindSectionHeader, withReuseIdentifier: "Header") collectionView.backgroundColor = .white return collectionView }() private lazy var _dataSource: DataController = .init(adapter: .init(collectionView: self.collectionView)) private let section0 = Section(ModelA.self, isEqual: { $0.identity == $1.identity }) var section0Models: [ModelA] = [] { didSet { _dataSource.update( in: section0, items: section0Models, updateMode: .partial(animated: true), completion: { }) } } override func viewDidLoad() { super.viewDidLoad() collectionView.delegate = self collectionView.dataSource = self _dataSource.add(section: section0) for _ in 0..<20 { section0Models.append(ModelA(identity: UUID().uuidString, title: String.randomEmoji())) } view.addSubview(collectionView) //This return zero items even though section0Models has 20 items _dataSource.numberOfItems(in: section) } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. } func numberOfSections(in collectionView: UICollectionView) -> Int { return _dataSource.numberOfSections() } func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { return _dataSource.numberOfItems(in: section) } func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "Cell", for: indexPath) as! Cell let m = _dataSource.item(at: indexPath, in: section0) cell.label.text = m.title return cell } func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView { if kind == UICollectionElementKindSectionHeader { let view = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: "Header", for: indexPath) as! Header view.label.text = "Section " + indexPath.section.description return view } fatalError() } func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForHeaderInSection section: Int) -> CGSize { return CGSize(width: collectionView.bounds.width, height: 50) } func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize { return CGSize(width: collectionView.bounds.width / 6, height: 50) } }