4

There seems to be a similar question here but it didn't solve my problem.

I created two collectionViews in my viewController as follows :

let y = self.view.frame.height
titleView  = UIView(frame : CGRect(x: 0 , y:  50 , width: self.view.frame.width, height: y - 100 ))

let middle = CGPoint(x: 10, y:   titleView.bounds.height/10)
let frame = CGRect(origin: middle , size: CGSize(width: self.view.frame.width - 20 , height: 70))
let layout = UICollectionViewFlowLayout()
fontCollection = UICollectionView(frame: frame, collectionViewLayout: layout)
fontCollection.dataSource = self
fontCollection.delegate = self
fontCollection.register(UICollectionViewCell.self, forCellWithReuseIdentifier: "fontsIdentifier")
fontCollection.backgroundColor = UIColor.white
// Do any additional setup after

colorCollection  = UICollectionView(frame: frame, collectionViewLayout: layout)
//colorCollection.frame.origin.y = fontCollection.frame.origin.y + (2 * fontCollection.frame.height)
colorCollection.dataSource = self
colorCollection.delegate = self
colorCollection.register(UICollectionViewCell.self, forCellWithReuseIdentifier: "colorsIdentifier")
colorCollection.backgroundColor = UIColor.white
// Do any additional setup after

These are my UICollectionViewDataSource methods :

func numberOfSections(in collectionView: UICollectionView) -> Int {
    collectionView.reloadData()
    collectionView.collectionViewLayout.invalidateLayout()
    return 1
}

public func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    if(collectionView == self.colorCollection ){
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "colorsIdentifier", for: indexPath)
        cell.backgroundColor = .darkGray
        return cell
    } else {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "fontsIdentifier", for: indexPath)
        cell.backgroundColor = .gray
        return cell
    }
}

Then I use a segmented control to switch between the two collectionViews. Everything goes as desired upto this point.However when I want to allocate different number of cells to either collectionView I get this error :

UICollectionView received layout attributes for a cell with an index path that does not exist: {length = 2, path = 0 - 6}

This is my numberOfItemsInSection method

public func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {

     if(collectionView == self.colorCollection ){ return 9 }
     else if(collectionView == self.fontCollection ){  return 6  }

     return 0
}

Am I doing something wrong? What am I missing?

Dávid Pásztor
  • 51,403
  • 9
  • 85
  • 116
209135
  • 517
  • 5
  • 15
  • Refer this https://stackoverflow.com/a/39919303/4611751 – Rajesh73 Sep 01 '17 at 11:43
  • I referred to the solution in this link but unfortunately this doesn't seem to solve my problem. – 209135 Sep 01 '17 at 11:49
  • Post your code that reloads collectionview – Rajesh73 Sep 01 '17 at 11:50
  • I have updated my code. Please have a look. – 209135 Sep 01 '17 at 11:56
  • Reloading collectionview inside its datasource methods is not advisable. Please do it outside, like in viewdidload or somewhere else. – Rajesh73 Sep 01 '17 at 11:57
  • Yes @Rajesh73 is right, please do that reloadData outside the datasource methods and try to put the invalidatelayout after – TomCobo Sep 01 '17 at 12:02
  • For the purpose of testing I am simply looking to create two collectionViews with different number of cells. I don't understand why I need to reload my collectionViews . An important observation I made is that the error goes away if I have the same return value for both collectionViews in the `numberOfItemsInSection` method OR a greater return value for the `fontCollection` . – 209135 Sep 01 '17 at 12:06
  • Unfortunately reloading and invalidating both the `collectionViews` in different places like `viewDidLoad` / `viewDidAppear` and other functions didn't solve the problem either. – 209135 Sep 01 '17 at 12:16
  • 1
    Then guessing here, Could it be the same layout assigned to both collectionview causing the issue? – Rajesh73 Sep 01 '17 at 12:18
  • Miraculously worked! . I gave both collectionViews different layouts and it fired off. Thanks a ton. – 209135 Sep 01 '17 at 12:24

1 Answers1

3

As @Rajesh73 pointed out in the comment , the problem was in assigning one layout to both the collectionViews. So I gave the both collectionViews different layouts and it solved the problem.

Thus replacing

  let layout =              UICollectionViewFlowLayout()
  fontCollection  =         UICollectionView(frame: frame, collectionViewLayout: layout)
  colorCollection  =        UICollectionView(frame: frame, collectionViewLayout: layout)

with

  let fontsLayout =      UICollectionViewFlowLayout()
  fontCollection  =      UICollectionView(frame: frame,collectionViewLayout: fontsLayout)
  let colorsLayout =      UICollectionViewFlowLayout()
 colorsCollection  =     UICollectionView(frame: frame collectionViewLayout: colorsLayout)

solved the issue.

209135
  • 517
  • 5
  • 15
  • 1
    wasted 2 hours figuring out the same problem. Damn, never thought sharing same layout for two collectionviews will create this kind of problem. Saved my life. – Anuran Barman Jan 24 '22 at 07:49