UICollectionReusableView 内的 UICollectionViewCells 没有被渲染?

Posted

技术标签:

【中文标题】UICollectionReusableView 内的 UICollectionViewCells 没有被渲染?【英文标题】:UICollectionViewCells inside UICollectionReusableView not being rendered? 【发布时间】:2019-11-13 08:24:20 【问题描述】:

我有一个 collectionView 标题,里面有一个水平的 collectionView [主要的 collectionView 是垂直的]。

标题被渲染出来,但是,我没有得到水平collectionView的模型计数

我已确保以下内容;

collectionViews'delegatedataSource 都设置为 self 正在检索数据 我在.main 队列的两个collectionViews 上调用.reloadData()

标题代码

private var collectionViewHeader: ExploreTableHeaderView = 
        let view = ExploreTableHeaderView()
        return view
    ()

class ExploreTableHeaderView: UICollectionReusableView 
    let collectionView: UICollectionView = 
        let layout = UICollectionViewFlowLayout()
        layout.scrollDirection = .horizontal
        layout.minimumInteritemSpacing = 16
        layout.minimumLineSpacing = 0
        let view = UICollectionView(frame: .zero, collectionViewLayout: layout)
        view.backgroundColor = .orange
        view.contentInset = UIEdgeInsets(top: 0, left: 16, bottom: 0, right: 16)
        view.alwaysBounceHorizontal = true
        view.showsHorizontalScrollIndicator = false
        view.allowsSelection = true
        view.translatesAutoresizingMaskIntoConstraints = false
        view.register(ExploreCategoryCollectionViewCell.self, forCellWithReuseIdentifier: Identifier.categoryCell)
        return view
    ()

// Override frame, addSubView etc...

头文件实现

func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView 
    switch kind 
    case UICollectionView.elementKindSectionHeader:
        let headerView = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: Identifier.headerCell, for: indexPath) as! ExploreTableHeaderView
        return headerView
    default:
    return UICollectionReusableView()
    

数据源

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell 
    if collectionView == collectionViewHeader.collectionView 
        if let cell = collectionView.dequeueReusableCell(withReuseIdentifier: Identifier.categoryCell, for: indexPath) as? ExploreCategoryCollectionViewCell 
            let category = self.categories[indexPath.item]
            cell.category = category
            return cell
        
     else 
        if let cell = collectionView.dequeueReusableCell(withReuseIdentifier: Identifier.itemCell, for: indexPath) as? ExploreItemCollectionViewCell 
            let item = self.recentItems[indexPath.item]
            cell.item = item
            return cell
        
    
    return UICollectionViewCell()

重新加载视图

private var categories = [Category]() 
        didSet 
            DispatchQueue.main.async 
                self.collectionViewHeader.collectionView.reloadData()
            
        
    

    private var recentItems = [Item]() 
        didSet 
            DispatchQueue.main.async 
                self.itemsCollectionView.reloadData()
            
        
    

【问题讨论】:

【参考方案1】:

您能否详细说明如何设置委托和数据源?

你说collectionViews delegate和dataSource都设置为self,但我没有看到代码,所以我的假设是你提到的self对于每个collectionViews都是不同的

我的假设是您需要在这行代码中设置委托和数据源

private var collectionViewHeader: ExploreTableHeaderView?

func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView 
        switch kind 
        case UICollectionView.elementKindSectionHeader:
            let headerView = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: Identifier.headerCell, for: indexPath) as! ExploreTableHeaderView
        headerView.collectionView.dataSource = self
        headerView.collectionView.delegate = self
        collectionViewHeader = headerView
            return headerView
        default:
        return UICollectionReusableView()
        
    

编辑: 这里示例代码 https://github.com/aiwiguna/CollectionViewReuse

【讨论】:

我在 ViewDidLoad() collectionView 和 headerView.collectionView 中都设置了它们 我认为你不能在 viewDidload() 中这样做,因为你在 func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) 中使用 dequeueReusableSupplementaryView,它的不同实例,你试试我上面分享的代码? 因为使用dequeueReusableSupplementaryView,所以不要为ExploreTableHeaderView新建实例 @DavidLintin 我更新了代码,你可以查看更新的代码 等等,我会创建一些示例项目

以上是关于UICollectionReusableView 内的 UICollectionViewCells 没有被渲染?的主要内容,如果未能解决你的问题,请参考以下文章

Swift - UICollectionReusableView 的子视图不适合宽度

未显示自定义 UICollectionReusableView 元素

显示部分标题 UICollectionReusableView

UICollectionReusableView 中未调用委托

协议和委托不适用于 UICollectionReusableView

UICollectionReusableView 中的标签始终为零