4

When trying to create collapsible UICollectionView sections, I update the number of items in the section dependent on its state. However, doing it this way, I reload the section which also reloads the section header aswell, and I get a very weird behavior when animating my image in the section header.

Essentially, reloading the section header when changing section items enables the UICollectionView to update the items but the section animate looks and behaves strange. Without calling reloadSection, it allows for the proper animation but the items do not load.

self?.collectionView?.performBatchUpdates({ 
   let indexSet = IndexSet(integer: section)
   self?.collectionView?.reloadSections(indexSet) 
}, completion: nil)

What is the fix for this?

mugx
  • 9,869
  • 3
  • 43
  • 55
NojDavid
  • 89
  • 1
  • 10

1 Answers1

4

You may try to extract the sequence of IndexPath in a specific section, then call reloadItems on such sequence, doing so:

extension UICollectionView {
   func reloadItems(inSection section:Int) {
      reloadItems(at: (0..<numberOfItems(inSection: section)).map {
         IndexPath(item: $0, section: section)
      })
   }
}

so your code might be something like:

var updateSection = 0 // whatever
collectionView.performBatchUpdates({
    // modify here the collection view
    // eg. with: collectionView.insertItems
    // or: collectionView.deleteItems
}) { (success) in
    collectionView.reloadItems(inSection: updateSection)
}
mugx
  • 9,869
  • 3
  • 43
  • 55
  • Im doing this in reloadSection: self?.collectionView?.performBatchUpdates({ let indexSet = IndexSet(integer: section) self?.collectionView?.reloadSections(indexSet) }, completion: nil) – NojDavid Jan 20 '18 at 00:52
  • 2
    I did. It gives me an error I had before. Invalid update: invalid number of items in section 1. The number of items contained in an existing section after the update (3) must be equal to the number of items contained in that section before the update (0), plus or minus the number of items inserted or deleted from that section (0 inserted, 0 deleted) and plus or minus the number of items moved into or out of that section (0 moved in, 0 moved out). – NojDavid Jan 20 '18 at 00:57
  • That's another problem, from your console I see that you are modifying the collection view, I guess you should clarify the question with the full code involved. Anyway, the reloadItems should be called in the completion of `performBatchUpdates` (after the collection view did the synchronization) – mugx Jan 20 '18 at 01:02
  • I'm managing my items like this, is this not correct? func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { if let item = items[section] as? FactViewModelItem{ if item.type != .profileHeader { if item.isCollapsible && item.isCollapsed { return 0 } } } return items[section].rowCount } – NojDavid Jan 20 '18 at 01:28