G.Abhisek G.Abhisek - 3 months ago 10
Swift Question

Datasource methods not being called properly when implemented in custom UICollectionView class

Scenario - I have to create a custom UICollectionView class programmatically which has to be presented in any place I want.

Code till now -

For custom UICollectionView

class ABSegmentView: UICollectionView,UICollectionViewDelegateFlowLayout,UICollectionViewDataSource {

var segmentProperties=segmentControlProperties()//segmentControlProperties is a modal class having relevant details regarding about population of collection view.
override init(frame: CGRect, collectionViewLayout layout: UICollectionViewLayout) {
super.init(frame: frame, collectionViewLayout: layout)
self.dataSource = self
self.delegate = self
self.registerClass(UICollectionViewCell.self, forCellWithReuseIdentifier: "cellIdentifier")

}

required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}

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

func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
print(segmentProperties.titleArray)
return segmentProperties.titleArray.count//data properly being received over here
}

//not getting called
func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {

let cell = self.dequeueReusableCellWithReuseIdentifier("cellIdentifier", forIndexPath: indexPath)
cell.backgroundColor = UIColor.redColor()
return cell
}


func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize{
return CGSizeMake(self.segmentProperties.segmentHeight, self.segmentProperties.segmentWidth)
}




}


Code for adding this collection view in some place -

let segment = ABSegmentView(frame: CGRectMake(0, 0, 200, 200), collectionViewLayout: UICollectionViewLayout())
segment.segmentProperties.segmentWidth = 60
segment.segmentProperties.segmentHeight = 50
segment.segmentProperties.titleArray = ["heyy","heyy","heyy","heyy","heyy","heyy"]
self.view.addSubview(segment)


So what is getting added is only an empty collection view.

Reason Figured out -

On debugging I found that my data source method
cellForItemAtIndexPath()
&
func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: NSIndexPath)
are not getting called.

Question - I am not sure what I am doing for my required scenario is the right implementation or not. Please amend me if I am missing something somewhere or what might be my mistakes.

Edit :
Answer -
Thanks to Santosh's answer. I figured out that I misunderstood the concept of
collectionViewLayout
.

Findings -


  • I have to set a proper flow layout for the collection view as a
    proper flow layout with correct spacing and other values are quite
    essential for a collection view to be properly laid.

    CollectionView Flow layout is what lays the UI of collection view i.e the grid view.

    There are many questions in StackOverflow which relates of data source methods not being called due to improper laying of collectionViewFlowLayout.



References that worked out for me apart from accepted answer -

http://stackoverflow.com/a/14681999/5395919

Other instances when some one can encounter such problems -

-When we set our cell size quite bigger than our collection view.

-When our cell layout size is too big or isn't appropriately held by the collection view.

Answer

You are using UICollectionViewLayout to instantiate your custom collectionView with layout. Try using UICollectionViewFlowLayout. Below code may help you, let me know if it works:

let layout = UICollectionViewFlowLayout()
layout.minimumInteritemSpacing = 20//you can change this value
layout.scrollDirection = .Vertical//or may be .Horizontal

let segment = ABSegmentView(frame: CGRectMake(0, 0, 200, 200), collectionViewLayout: layout)
segment.segmentProperties.segmentWidth = 60
segment.segmentProperties.segmentHeight = 50
segment.segmentProperties.titleArray = ["heyy","heyy","heyy","heyy","heyy","heyy"]
self.view.addSubview(segment)
segment.reloadData()