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

Posted

技术标签:

【中文标题】如何使用自定义 UICollectionReusableView 作为集合视图的部分标题?【英文标题】:How to use custom UICollectionReusableView as section header of collection view? 【发布时间】:2020-04-05 18:11:13 【问题描述】:

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

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

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

let friendHeader = collectionView.dequeueReusableSupplementaryView(ofKind: kind, 
                                    withReuseIdentifier: "FriendHeaderView", 
                                    for: indexPath) as! FriendHeaderView

下面是sn-p的代码:

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")
    

现在是数据源实现:

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")
        

    


而且我不知道为什么还需要实现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
    



好的,现在进入正题:上面提到的崩溃不会发生 如果我不使用as! 运营商的话。好吧,如果我使用部分 来自故事板的标题而不是UINib注册,有 没有崩溃。

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


如何使用从界面构建器构建的多个类型标题?


我已经根据上面所说的内容创建了demo project。如果有人有兴趣,请检查一下。

【问题讨论】:

【参考方案1】:

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

【讨论】:

太棒了。其实就是这样。但我认为它需要为将来遇到同样问题的读者提供详细的答案。为此,我正在添加另一个答案。【参考方案2】:

好吧,经过更多调查和@good4pc 在接受的答案中的输入(实际上我在查看答案之前自己发现了这一点)似乎问题实际上是由于 Xcode 的一些不需要的问题而发生的

当我们使用.xib 创建任何视图(最好是UITableViewCellUICollectionViewCell)时,会在身份检查器中自动为.xib 提供类身份。但UICollectionReusableView 的情况并非如此。请参阅下面随附的屏幕截图以便于理解。

这是UICollectionViewCell 的子类.xib

这是一个UICollectionReusableView 的子类.xib


所以关键是提供.xib文件的类标识 由属性检查器完成。

【讨论】:

以上是关于如何使用自定义 UICollectionReusableView 作为集合视图的部分标题?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 2 个或更多自定义单元格创建自定义 UICollectionView?

如何在shader中使用自定义函数

如何创建自定义 JQuery 函数以及如何使用它?

代码调试篇:如何编写 gdb 自定义命令

代码调试篇:如何编写 gdb 自定义命令

PHP 如何:使用自定义查询基于自定义字段显示帖子