Tuesday, August 15, 2017

UICollectionView Crash on reloadData

Leave a Comment

UICollectionview is loaded with simple cells and there is a simple int variable for calculating the number of items in the section.

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

When the value of viewCount (initially at 45) is changed to a lower number (say 12) the app crashes.

This is error message to update the item count:

 *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'UICollectionView received layout attributes for a cell with an index path that does not exist: <NSIndexPath: 0x17402fbe0> {length = 2, path = 0 - 12}' 

I tried reloading data and invalidating the cache as well as said here. This didn't help. I also tried reloading the indexSet before invalidating the cache. That didn't help either.

    func textFieldShouldReturn(_ textField: UITextField) -> Bool {         if textField == countTextField {             viewCount = Int(textField.text!)!             textField.resignFirstResponder()             let indexSet = IndexSet(integer: 0)  //            collectionView.reloadSections(indexSet)             collectionView.reloadData()             collectionView.collectionViewLayout.invalidateLayout()         }          return true     } 

I use 2 custom UICollectinViewLayout and I also set shouldInvalidateLayout to be true. Any help?

Update

func numberOfSections(in collectionView: UICollectionView) -> Int {         return 1     }      func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {         let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "DemoCell", for: indexPath) as! DemoCollectionViewCell         cell.indexLabel.text = "\(indexPath.item + 1)"          return cell     }      @IBAction func showLayout1(_ sender: Any) {         currentLayout = DemoACollectionViewLayout()         animateLayout()     }      @IBAction func showLayout2(_ sender: Any) {         currentLayout = DemoBCollectionViewLayout()         animateLayout()     }      func animateLayout() {         UIView.animate(withDuration: 0.3) { [weak self] value in             guard let `self` = self else { return }             self.collectionView.collectionViewLayout.invalidateLayout()             self.collectionView.collectionViewLayout = self.currentLayout!         }     } 

Here is the sample project.

Update: I have updated to use an dataObject to reload the UICollectionView but the cache in UICollectionViewLayout is not being cleared when I invalidate.

1 Answers

Answers 1

The cache must be cleared when the number of items for the collectionView has changed.

guard let views = collectionView?.numberOfItems(inSection: 0)             else {     cache.removeAll()     return }  if views != cache.count {     cache.removeAll() }  if cache.isEmpty {     //Layout attributes } 
If You Enjoyed This, Take 5 Seconds To Share It

0 comments:

Post a Comment