0
votes

I have a UICollectionView with an custom layout so I can scroll both horizontal and vertical at the same time in an excell-like view.

I have two prototype cells with two custom CollectionViewCells classes. One for content and one for the header because I want them to look different. My sections are run vertical, every column is a new section. I would like to have a custom header for each section.

At the moment I have a working roster of cells. I have implemented the following for the header.

CustomCollectionViewController:

  • register the header cell (in viewDidLoad)
  • implemented numberOfSectionsInCollectionView, numberOfItemsInSection, cellForItemAtIndexPath
  • viewForSupplementaryElementOfKind

r

  collectionView?.registerClass(CustomCollectionViewHeaderCell.self, forSupplementaryViewOfKind: UICollectionElementKindSectionHeader, withReuseIdentifier: reuseIdentifierHeader)

override func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> CustomCollectionViewCell {
    let cell = collectionView.dequeueReusableCellWithReuseIdentifier(reuseIdentifier, forIndexPath: indexPath) as! CustomCollectionViewCell
    cell.label.text = "S:\(indexPath.section) / i:\(indexPath.item)" 
    return cell
}

override func collectionView(collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, atIndexPath indexPath: NSIndexPath) -> UICollectionReusableView {   
    if kind == UICollectionElementKindSectionHeader {
        let cell = collectionView.dequeueReusableSupplementaryViewOfKind(kind, withReuseIdentifier: reuseIdentifierHeader, forIndexPath: indexPath) as! CustomCollectionViewHeaderCell
        cell.backgroundColor = UIColor.redColor()
        return cell
    }

    abort()
}

CustomCollectionViewLayout:

  • prepareLayout -> Generate cells,
  • layoutAttributesForItemAtIndexPath -> return content cells
  • layoutAttributesForSupplementaryViewOfKind -> return header cells

        // Generate cell data
    if collectionView?.numberOfSections() > 0 {
        // If collection view has sections
    
        for section in 0...(collectionView?.numberOfSections())!-1 {
            // For every section
    
            if collectionView?.numberOfItemsInSection(section) > 0 {
                // If section have items
                // Skip item 0
                for item in 1...(collectionView?.numberOfItemsInSection(section))!-1{
                    // For every item
    
                    // Create individual cell variables
                    let cellIndex = NSIndexPath(forItem: item, inSection: section)
                    let xPos = CGFloat(section) * CELL_WIDTH
                    let yPos = CGFloat(item) * CELL_HEIGHT
    
                    // Create cell attributes object
                    let cellAttr = UICollectionViewLayoutAttributes(forCellWithIndexPath: cellIndex)
                    cellAttr.frame = CGRectMake(xPos, yPos, CELL_WIDTH, CELL_HEIGHT)
    
                    // Safe in dictionary
                    cellAttributesDictionary[cellIndex] = cellAttr
    
                }
            }
    
    
            // Generate header cells
            let cellIndex = NSIndexPath(forItem: 0, inSection: section)
            let xPos = CGFloat(section) * CELL_WIDTH
            let yPos = CGFloat(1) * CELL_HEIGHT
    
            // Create cell attributes object
            let cellAttr = UICollectionViewLayoutAttributes(forCellWithIndexPath: cellIndex)
            cellAttr.frame = CGRectMake(xPos, yPos, CELL_WIDTH, CELL_HEIGHT)
            cellAttr.zIndex = 1
            cellAttr.zIndex = 5
    
            headerCellAttributesDictionary[cellIndex] = cellAttr
    
        }
    }
    
    
    
    override func layoutAttributesForElementsInRect(rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
    let array = cellAttributesDictionary.values
    
    // Loop over all cells
    // Place all cells currently in view in an array
    var layoutAttrinRect = [UICollectionViewLayoutAttributes]()
    for cellAttr in array {
        if(CGRectIntersectsRect(rect, cellAttr.frame)){
            layoutAttrinRect.append(cellAttr)
        }
    }
    
    return layoutAttrinRect
    

    }

The problem is that the cells are never shown. Non of the code that should implements the header is called. I'm fairly new to this and try to challenge myself with more difficult exercises, so it might be something basic.

No error is shown. The app starts with the normal excell like table without headers.

Anyone an idea what I could be doing wrong?

1
Are you building your views in Storyboard?pbush25
yes, mainly. Until I get to the headers. It's impossible to add a header via the storyboard when a custom layout is in place.control-panel
Okay then let me rephrase my question, did you build your header in the storyboard and give it a reuseIdentifier?pbush25
yes, I have two prototype cells with different reuseIdentifiers. One for the content and one for the header.control-panel
Did you ever solve this?Just a coder

1 Answers

2
votes

When building prototype cells (or headers) in the Storyboard, you should not register the cell for that class on the collectionView in code. This will overwrite your existing view and they won't appear.