I've added a UISearchBar
to a UICollectionView
and in the delegate searchBar:textDidChange:
filter my model and call [collectionView reloadData]
. reloadData
(as well as reloadSection, etc) wants to take away firstResponder from the searchbar's textfield, thus dismissing the keyboard.
I am trying to build a "live updating" filter and so it's annoying to have the keyboard go away after each character typed.
Any ideas?
Solved it:
I just added
after calling
If you've added the
UISearchBar
as a header to theUICollectionView
thereloadData
call will "refresh" the header by removing and re-adding theUISearchBar
causing it to losefirstResponder
.You can either add your
UISearchBar
in another way, not using header, or overridereloadData
, check if the search bar is currently firstResponder, and if so after callingsuper
, do:Here's how I managed it. I had my UISearchBar as the header supplementary view in my collection view. On text didchange for the searchbar delegate I set a flag that the search is active (or not) and reloaded the collectionview
Then in the cellForItemAtIndexPath I check if the keyboard is first responder and search is active, if not, I make it first responder:
I run into the same problem recently and it took a while to get it fixed. The problem is that when text field is nested in ReusableCollectionView the following doesn't work.
Furthermore, for me it did work fine on simulator but didn't work on the device.
Setting view controller as text field delegate and implementing
didn't work because as the result collection view did not refresh. My guess is - before reloading its views collection tries to remove focus from all nested controls but it can't - we return NO from text field delegate method.
So the solution for me was to let the system remove focus from text field but then get it back after reload. The question was when actually to do that.
First, I've tried to do it in the
but when there was no items in collection (which is normal case during filtering) this method didn’t get called.
Eventually I solved this in the following way. I created UICollectionReusableView subclass implementing two methods: -prepareForReuse and -drawRect:. The first one contains -setNeedsDesplay call which schedules drawRect call on next drawing cycle. The second one restores focus by calling [self.textField becomeFirstResponder] if corresponding flag is set to YES. So the idea was to call becomeFirstResponder "later" but not too late, otherwise weird "jumping" of keyboard happens.
My custom reusable collection view looks like this:
Then in my View Controller:
Probably not the most elegant solution, but it works. :)
The answer is to not reload the section which has the text field. I solved this problem by placing all items into a single search so it was possible to reload that single section.
The existing screen that I was modifying was showing the index on the right with the letters to navigate to each section which means there were many section which makes it harder to know how to reload each of those sections without messing up internal state. To make it work when the text field becomes the first responder the organization of the collection view changes to place all items into a single section which is reloaded when the search is run. Now the top section is not reloaded so it does not lose focus.
This way no undefined behavior is necessary like the other answers listed for this question.
https://github.com/brennanMKE/PullDownSearch