I\'ve added a UISearchBar to a UICollectionView and in the delegate searchBar:textDidChange: filter my model and call [collectio
This is due to reloadData() being called inside of UISearchBarDelegate methods. A way around this is to have an extra empty section specifically for your header view that contains the search bar. Then instead of reloadData() call:
self.collectionView.reloadSections([1])
If you do not have multiple sections of data you can eliminate the second header by loading a faux header.
override func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView {
if indexPath.section == 1 {
let fakeView = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: "fakeHeader", for: indexPath)
return fakeView
}
let headerView = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: searchHeader, for: indexPath) as! SearchHeader
headerView.initializeHeader(with: self)
return headerView
}
Next you can set the height of the faux header to 0
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForHeaderInSection section: Int) -> CGSize {
return section == 0 ? CGSize(width: collectionView.frame.width, height: 260) : CGSize(width: collectionView.frame.width, height: 0)
}
The next problem you will run into will be the gap between the cells and the first header which is caused by the edge insets. So eliminate the top and bottom insets for the first section.
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
if section == 1 {
return UIEdgeInsets(top: 20, left: 20, bottom: 30, right: 20)
}
return UIEdgeInsets(top: 0, left: 20, bottom: 0, right: 20)
}
Hope this saves someone some time.