Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

UICollectionView content is hidden after reloadData

I have a UICollectionView that displays content from an NSFetchedResultsController. The collectionView has one section, and in that section there's a header. The header allows the user to filter the content in the collection view. The header view's delegate is connected to the UIViewController containing the collection view.

As soon as the user changes one of the filter options, the header view fires a message to its delegate. The delegate changes the predicate on the fetchRequest of its NSFetchedResultsController and calls -[NSFetchedResultsController performFetch:]. Next, the collection view has to be notified that the content has changed. This can be done in several ways, but the way I prefer is by calling -[UICollectionView reloadData]. Unfortunately this method does not work like expected: the entire collection view disappears when I call this method. These are some of the observations I made regarding this issue:

  1. All cells and the header of the first (and only) section have their hidden flag set to YES. I tried to trace what method caused this by setting a symbolic breakpoint on -[UIView setHidden:]. Unfortunately it never breaks inside a UICollectionView subview.
  2. collectionView:cellForItemAtIndexPath: is never called after calling -[UICollectionView reloadData].
  3. collectionView:viewForSupplementaryElementOfKind:atIndexPath: is never called after calling -[UICollectionView reloadData].
  4. numberOfSectionsInCollectionView: is still called and still returns the correct number (1 in this case).
  5. collectionView:numberOfItemsInSection is still called and still returns the correct number (1 in this case).

What I have tried so far to solve the issue:

  1. disabling all customizations (sectionInset, itemSize) on the UICollectionViewFlowLayout instance
  2. disabling all customizations (separatorInset) on the UICollectionView instance
  3. have the header added as a subview to UICollectionView and setting the contentInset accordingly. Unfortunately UICollectionView does not like me to temper with its auto layout constraints and crashes when I do so.
  4. call [UICollectionView reloadSections:] instead of [UICollectionView reloadData]. This works but I don't like the animation.
  5. manually insert, delete and update rows in the first section. This works as long as the view controller containing the collection view is in memory. As soon as it deallocates, the app crashes with an assertion failure in -[UICollectionView dealloc].

It does not feel right to have the header setup this way, but unfortunately UICollectionView does not have a global header like UITableView (tableHeaderView).

like image 278
datwelk Avatar asked Sep 30 '13 08:09

datwelk


Video Answer


1 Answers

Try to Reload them in the main thread

dispatch_async(dispatch_get_main_queue(), ^{
[self.collectionView reloadData];
});

it worked for me

like image 166
Yahia Avatar answered Nov 14 '22 22:11

Yahia