Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

ios

swift

xcode7

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

}
like image 818
Himerzi Avatar asked Jan 18 '16 03:01

Himerzi


People also ask

What is collection view in Swift?

A collection view manages an ordered set of content, such as the grid of photos in the Photos app, and presents it visually. Collection views are a collaboration between many different objects, including: Cells. A cell provides the visual representation for each piece of your content.

How do I register a collection view cell?

Use a cell registration to register cells with your collection view and configure each cell for display. You create a cell registration with your cell type and data item type as the registration's generic parameters, passing in a registration handler to configure the cell.

What is the difference between table view and collection view?

Table view presents data in multiple rows arranged in a single column, the cell design is fit as a row. However, collection view can create rows and columns, it can design cells in various ways, even if they are not necessarily rows. It's also the biggest feature of a collection view cell.


2 Answers

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.

like image 168
Dallas Johnson Avatar answered Oct 18 '22 04:10

Dallas Johnson


My hypothesis would be that since this is happening inside cells of a UITableView, whenever a table view cell gets put back in the "reuse pool", the delegates of the collection view get disconnected or disabled. This would depends on the code that provide cells to the table view (which we're not seeing in the code sample).

There could also be some code elsewhere that clears the datasource from the collection view. (unlikely but worth checking)

like image 3
Alain T. Avatar answered Oct 18 '22 04:10

Alain T.