如何使用自定义 UICollectionReusableView 作为集合视图的节标题?

nay*_*yem 3 ios uicollectionview uicollectionreusableview swift

我已经被逼疯了好几个小时了,因为我无法解决这个问题。

我有一个集合视图,它可以有不同的部分和不同的编号。每个中的项目数。对于每个部分,我需要使用不同类型的节标题。因此,为此,我将使用UICollectionReusableView. 但我似乎无法成功地UICollectionReusableView通过UINib注册方式使用自定义子类。

当我将可重用视图向下转换为我的子类时,会发生崩溃。喜欢:

let friendHeader = collectionView.dequeueReusableSupplementaryView(ofKind: kind, 
                                    withReuseIdentifier: "FriendHeaderView", 
                                    for: indexPath) as! FriendHeaderView
Run Code Online (Sandbox Code Playgroud)

下面是代码片段:

class ViewController: UIViewController {

    @IBOutlet weak var collectionView: UICollectionView!

    private let viewModel = ProfileViewModel()

    override func viewDidLoad() {
        super.viewDidLoad()
        collectionView.dataSource = self
        collectionView.delegate = self
        // more code
        collectionView.register(UINib(nibName: "FriendHeaderView", bundle: nil), 
                                forSupplementaryViewOfKind: UICollectionView.elementKindSectionHeader, 
                                withReuseIdentifier: "FriendHeaderView")
    }
}
Run Code Online (Sandbox Code Playgroud)

现在这是数据源的实现:

extension ViewController: UICollectionViewDataSource {

    func numberOfSections(in collectionView: UICollectionView) -> Int {
        // valid implementation
    }

    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        // valid implementation
    }

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {

        // valid implementation

    }

    func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView {

        switch kind {
        case UICollectionView.elementKindSectionHeader:
            let friendHeader = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: "FriendHeaderView", for: indexPath) as! FriendHeaderView

            // *** Crash happens here *** //

            return friendHeader
        default:
            assert(false, "Invalid element type")
        }

    }

}
Run Code Online (Sandbox Code Playgroud)

我不知道为什么collectionView(_:layout:referenceSizeForHeaderInSection:)还需要实施。所以这里是:

extension ViewController: UICollectionViewDelegateFlowLayout {
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForHeaderInSection section: Int) -> CGSize {
        let size = CGSize(width: collectionView.bounds.width, height: 100)
        return size
    }

}
Run Code Online (Sandbox Code Playgroud)

好吧,现在进入正题:如果我不沮丧地使用操作员,上述崩溃根本不会发生as!。好吧,如果我使用情节提要中的节标题而不是UINib注册,则不会发生崩溃。

如果我需要多种类型标头,那么我也不能使用情节提要方法或不使用向下转换方法,因为我需要将数据提供给这些标头。


我该怎么做才能拥有多个类型标头以及从界面生成器构建的视图?


我用上面所说的内容制作了一个演示项目。如果有人感兴趣,请查看一下。

goo*_*4pc 5

一旦您在 Xib 文件中分配了正确的类和标识符,它就可以正常工作而不会崩溃。