Search code examples
iosswiftxcode7

Collection View isn't being displayed, cellForItemAtIndexPath is never called


I have a UITableView with custom cells containing UIStackView. As part of preparing a new cell, when the Table View adds new cells via its cellForRowAtIndexPath method, it instantiates and adds any collection views (of type MultaCollectionView) and any UILabel which need to be added to the cell’s Stack View (a cell may include various collection views). In theory, a stack view contains a sequence of Labels and Collection Views.

Although labels are displaying correctly, the Collection View is not being displayed at runtime. The Collection View I’m attempting to display is defined in a .xib Interface Builder document.

The Collection View’s numberOfSectionsInCollectionView method is getting called, however the collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) method is never called.

Why is the collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) method never called? Why aren’t Collection Views being rendered in the Stack View?

import UIKit
private let reuseIdentifier = "Cell"

class MultaCollectionView: UICollectionView, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout, UICollectionViewDelegate {
    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        self.delegate = self
        self.dataSource = self
    }
    class func instanceFromNib() -> UICollectionView {
        return UINib(nibName: "multas", bundle: nil).instantiateWithOwner(nil, options: nil)[0] as! UICollectionView
    }

    func numberOfSectionsInCollectionView(collectionView: UICollectionView) -> Int {
        return 1
    }


    func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return 2
    }

    func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCellWithReuseIdentifier(reuseIdentifier, forIndexPath: indexPath)
        return cell
    }

}

The parent TableView adds Cells via the following method:

func addSubviewsToCellStack(cell: ArticuloTableViewCell, texto: [[String: String]]) {\            
    if isLabel == true {
            let label = UILabel()
            label.text = "blah"
            subview = label
            cell.textoStack.addArrangedSubview(subview)
        } else {
            let colview = MultaCollectionView.instanceFromNib() 
            cell.textoStack.addArrangedSubview(colview)
        }                        
    }

}

Solution

  • Since you are getting the call back for the numberOfSectionsInCollectionView this would suggest the datasource is connected up correctly but if a cell is not going to be visible based on the current layout then the collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) will not get called until it is needed. The reason a cell might not be visible could be because your sectionInsets for the collectionView are set large enough that the first cell would be positioned outside the visible area of the collectionView.

    Another reason could be that the collectionView's frame is too small to display any cells. If your collectionview as a size of {0,0} you should get the calls as you are seeing to the numberOfSectionsInCollectionView but will not get the calls to cellForItemAtIndexPath since the cells will not be visible.

    Perhaps try ensuring that your collectionView has a frame size that is large enough to display the cells you expect to see. You may be seeing the UILabels correctly because they have an implicit intrinsicContentSize which ensures they display well in a stackView whereas the CollectionView is just as happy to have a size of 0,0 as it would be with any other size. Try giving the collectionView explicit width and height constraints to see if that helps.