如何在collectionView自定义布局中的其他补充标题单元格上方添加标题补充单元格

Posted

技术标签:

【中文标题】如何在collectionView自定义布局中的其他补充标题单元格上方添加标题补充单元格【英文标题】:How to add a header supplementary cell above other supplementary header cells In a collectionView custom layout 【发布时间】:2018-02-14 10:44:22 【问题描述】:

所以我有一个custom layout collectionView,看起来像这样:

我在@McDonal_11 的帮助下使用自定义布局[不是flowLayout] 完成了这项工作,它基本上允许我的collectionView 显示每个section,并将其项目放在单独的列中。

问题是我想添加一个supplementary header 上面所有这些supplementary headers 不是sections 的一部分。

类似这样的:

我应该怎么做?

【问题讨论】:

对于每个部分,我只添加了补充视图..!!喜欢这些输出。 ..!!你还需要什么? @McDonal_11 我刚刚添加了一张图片,以便您更好地理解我 你使用 CollectionViewcontroller 或 Viewcontroller ?? 我正在使用 ViewController,但我不希望主标题超出 collectionView,因为我需要主标题与 collectionView 一起滚动 那么,没问题。默认情况下,Section 0 和 item 0,即主 headerView。休息将是您的设计。在纵向和横向中,更改其宽度和高度。 【参考方案1】:

以下更改将接近该结果。

对于肖像,我已将 xPositionCell width 更改为 Section 0 和 item 0

对于横向,我已经更改了第 0 部分和第 0 项的 xPositionyPositionCell width

我做了一些逻辑,Cell 应该是SuperView 的中心。

override func prepare() 

    dataSourceDidUpdate = false

    if UIDevice.current.orientation == .landscapeLeft || UIDevice.current.orientation == .landscapeRight
    
        if let sectionCount = collectionView?.numberOfSections, sectionCount > 0 
            for section in 0...sectionCount-1 

                let maxNum = max(section, sectionCount + 1)
                let minNum = min(section, sectionCount + 1)

                let difference = maxNum - minNum

                var xPos = (Double(UIScreen.main.bounds.width) - (Double(difference) * CELL_WIDTH) - (Double(difference) * horizontalSpacing))

                var yPos : Double = 35.0

                if let rowCount = collectionView?.numberOfItems(inSection: section), rowCount > 0 

                    for item in 0...rowCount-1 


                        xPos = (Double(UIScreen.main.bounds.width) - (Double(difference) * CELL_WIDTH) - (Double(difference) * horizontalSpacing))

                        CELL_WIDTH = 100.0

                        let cellIndex = IndexPath(item: item, section: section)

                        if item == 0
                        
                            portrait_Ypos = headerSpacing + 30
                        
                        else
                        
                            portrait_Ypos = portrait_Ypos + CELL_HEIGHT + verticalSpaing
                        
                        yPos = portrait_Ypos

                        if section == 0 && item == 0
                        
                            xPos = 20
                            yPos = 0.0
                            CELL_WIDTH = (Double(UIScreen.main.bounds.width)) - 40
                        


                        let cellAttributes = UICollectionViewLayoutAttributes(forCellWith: cellIndex)
                        cellAttributes.frame = CGRect(x: xPos, y: yPos, width: CELL_WIDTH, height: CELL_HEIGHT)


                        xPos = (Double(UIScreen.main.bounds.width) - (Double(difference) * CELL_WIDTH) - (Double(difference) * horizontalSpacing))

                        CELL_WIDTH = 100.0
                        yPos = 35.0

                        // Determine zIndex based on cell type.
                        if section == 0 && item == 0 
                            cellAttributes.zIndex = 4
                         else if section == 0 
                            cellAttributes.zIndex = 3
                         else if item == 0 
                            cellAttributes.zIndex = 2
                         else 
                            cellAttributes.zIndex = 1
                        
                        cellAttrsDictionary[cellIndex] = cellAttributes

                    

                

            
        

        let contentWidth = Double(collectionView!.numberOfSections) * CELL_WIDTH + (Double(collectionView!.numberOfSections - 1) * horizontalSpacing)
        let contentHeight = Double(collectionView!.numberOfSections) * CELL_HEIGHT
        self.contentSize = CGSize(width: contentWidth, height: contentHeight)

        print("self.contentSizeself.contentSize     ", self.contentSize)
    
    else
    
        if let sectionCount = collectionView?.numberOfSections, sectionCount > 0 

            for section in 0...sectionCount-1 

                var xPos = (Double(UIScreen.main.bounds.width) - CELL_WIDTH) / 2.0

                if let rowCount = collectionView?.numberOfItems(inSection: section), rowCount > 0 
                    for item in 0...rowCount-1 

                        xPos = (Double(UIScreen.main.bounds.width) - CELL_WIDTH) / 2.0
                        CELL_WIDTH = 100.0

                        let cellIndex = IndexPath(item: item, section: section)

                        if section != 0
                        
                            if item == 0
                            
                                portrait_Ypos = portrait_Ypos + CELL_HEIGHT + headerSpacing
                            
                            else
                            

                                portrait_Ypos = portrait_Ypos + CELL_HEIGHT + verticalSpaing
                            
                        
                        else
                        
                            if item == 0
                            
                                portrait_Ypos = headerSpacing

                                xPos = 20
                                CELL_WIDTH = (Double(UIScreen.main.bounds.width)) - 40

                            
                            else
                            
                                portrait_Ypos = portrait_Ypos + CELL_HEIGHT + verticalSpaing
                            
                        

                        let cellAttributes = UICollectionViewLayoutAttributes(forCellWith: cellIndex)
                        cellAttributes.frame = CGRect(x: xPos, y: portrait_Ypos, width: CELL_WIDTH, height: CELL_HEIGHT)

                        xPos = (Double(UIScreen.main.bounds.width) - CELL_WIDTH) / 2.0
                        CELL_WIDTH = 100.0

                        if section == 0 && item == 0 
                            cellAttributes.zIndex = 4
                         else if section == 0 
                            cellAttributes.zIndex = 3
                         else if item == 0 
                            cellAttributes.zIndex = 2
                         else 
                            cellAttributes.zIndex = 1
                        
                        cellAttrsDictionary[cellIndex] = cellAttributes

                    

                

            
        

        let contentWidth = UIScreen.main.bounds.width
        let contentHeight = CGFloat(portrait_Ypos) + CGFloat(CELL_HEIGHT)
        self.contentSize = CGSize(width: contentWidth, height: contentHeight)

        print("sPort.contentSize     ", self.contentSize)
    




不要为第 0 节添加标题

override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? 

    var attributesInRect = [UICollectionViewLayoutAttributes]()

    for cellAttributes in cellAttrsDictionary.values 
        if rect.intersects(cellAttributes.frame) 

            attributesInRect.append(cellAttributes)

            let celIndPth = cellAttributes.indexPath

            if celIndPth.section != 0
            
                if celIndPth.item == 0
                
                    if let supplementaryAttributes = layoutAttributesForSupplementaryView(ofKind: UICollectionElementKindSectionHeader, at: cellAttributes.indexPath) 
                        attributesInRect.append(supplementaryAttributes)
                    

                
            

        
    

    return attributesInRect


override func layoutAttributesForItem(at indexPath: IndexPath) -> UICollectionViewLayoutAttributes? 

    return cellAttrsDictionary[indexPath]!


项目单元格

 override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell 
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier:  "Cell", for: indexPath) as! RulesCollectionViewCell
    cell.backgroundColor = UIColor.clear

    cell.layer.borderColor = UIColor(red: 83/255, green: 50/255, blue: 129/255, alpha: 1.0).cgColor
    cell.layer.borderWidth = 1.0
    cell.txtLbl.text = values[indexPath.section][indexPath.row]
    cell.txtLbl.textAlignment = .center
    cell.txtLbl.textColor = UIColor.white


    if indexPath.section == 0 && indexPath.row == 0
    
        cell.backgroundColor = UIColor.white
        cell.txtLbl.textColor = UIColor.red
    


    cell.layer.cornerRadius = 5

    cell.alpha = 1.0
    return cell

数组声明

let values = [["Main Header"],["a","b","c","d","e","f"], ["a","b","c"], ["a","b","c","d"], ["a","b","c","d","e","f"]]

输出

【讨论】:

以上是关于如何在collectionView自定义布局中的其他补充标题单元格上方添加标题补充单元格的主要内容,如果未能解决你的问题,请参考以下文章

自定义 CollectionView 布局重新加载数据不起作用

在我的自定义 collectionView 布局中未调用 prepare()

可重新排序的自定义 collectionview 布局

为 collectionView 中的每个其他项目设置特定布局

text CollectionView自定义布局

UICollectionView 中的自定义布局