可区分数据源和子类 UICollectionViewLayout - 如何添加补充标题?

问题描述 投票:0回答:0

我有一个

UICollectionView
使用
UICollectionViewDiffableDataSource
作为数据,我想添加一个补充标题。通常,我会使用
UICollectionViewCompositionalLayout
并通过在数据源对象上进行补充注册来实现这一点,例如:

let header = UICollectionView.SupplementaryHeaderRegistration<MyHeaderClass>(elementKind: UICollectionView.elementKindSectionHeader) { header, kind, indexPath in
    // configure header
}

// ...

dataSource.supplementaryViewProvider = { collectionView, kind, indexPath in
    return collectionView.dequeueConfiguredReusableSupplementary(using: header, for: indexPath)
}

并确保为标题指定

NSCollectionLayoutBoundarySupplementaryItem
并设置
NSCollectionLayoutSection
boundarySupplementaryItems

let headerSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0), heightDimension: .estimated(20))
let header = NSCollectionLayoutBoundarySupplementaryItem(layoutSize: headerSize, elementKind: UICollectionView.elementKindSectionHeader, alignment: .top)
section.boundarySupplementaryItems = [header]

但是,由于我无法使用组合布局,并且使用的是可区分数据源而不是

UICollectionViewDataSource
,我如何向集合视图布局添加补充标题? 或者我是否必须放弃可区分数据来源和使用
UICollectionViewDataSource
?

视图控制器:

class MyViewController: UIViewController {
    
    enum Section: Int, CaseIterable {
        case main
    }
    private var collectionView: UICollectionView!
    private var dataSource: UICollectionViewDiffableDataSource<Section, AnyHashable>!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        setupViewController()
        setupCollectionView()
        setupDataSource()
        updateData()
    }
    
    private func updateData() {
        var snapshot = NSDiffableDataSourceSnapshot<Section, AnyHashable>()
        snapshot.appendSections(Section.allCases)
        snapshot.appendItems(Array(0..<20), toSection: .main)
        dataSource.apply(snapshot, animatingDifferences: true)
    }
}

extension MyViewController: UICollectionViewDelegate {
    
    private func setupCollectionView() {
        collectionView = UICollectionView(frame: .zero, collectionViewLayout: makeLayout())
        collectionView.backgroundColor = .clear
        collectionView.delegate = self
        view.addSubviews([collectionView])
        collectionView.pinToContainerView(self.view)
    }
    
    private func setupDataSource() {
        let cell = UICollectionView.CellRegistration<MyCustomCell, AnyHashable> { cell, indexPath, item in
        }
        
        dataSource = UICollectionViewDiffableDataSource<Section, AnyHashable>(collectionView: collectionView) { collectionView, indexPath, item in
            return collectionView.dequeueConfiguredReusableCell(using: cell, for: indexPath, item: item)
        }
    }
    
    private func makeLayout() -> UICollectionViewLayout {
        return MyCustomLayout() // of type `UICollectionViewLayout`
    }
    
    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
        collectionView.deselectItem(at: indexPath, animated: true)
    }
}

extension MyViewController {
    
    private func setupViewController() {
        navigationItem.title = "Title"
        navigationItem.largeTitleDisplayMode = .never
        view.backgroundColor = .systemGroupedBackground
    }
}

自定义布局(经过修剪以仅显示我正在使用的方法):

class MyCustomLayout: UICollectionViewLayout {
    
    override func prepare() {
        super.prepare()
        // cell and column layout/position configuration
    }
    
    override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
        super.layoutAttributesForElements(in: rect)
        // cell attributes returned
    }

    override func layoutAttributesForItem(at indexPath: IndexPath) -> UICollectionViewLayoutAttributes? {
        // cell attributes returned
    }
}

ios swift uicollectionview uicollectionviewlayout diffabledatasource
© www.soinside.com 2019 - 2024. All rights reserved.