5

I have a UISearchBar for a UITableView and my implementation is as follows:

-(void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText
{
    [self.searchBar becomeFirstResponder];
    if(searchText.length == 0)
    {
        self.isFiltered = NO;     
    }
    else
    {
        NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF.writer1 contains[c] %@", searchText];
        self.isFiltered = YES;
        [[RTRepairOrderStore sharedStore] filterROArray:predicate];
    }

    [self.tableView reloadData];    
}

The issue is that after I type one letter into the search bar, the search works but the keyboard is immediately dismissed. How can I prevent this?

Giardino
  • 1,367
  • 3
  • 10
  • 30

4 Answers4

9

The searchBar is losing focus because it's likely located in the tableView header, and the tableView is being reloaded.

You can prevent this by either:

  • Moving the searchBar so it's no longer a subView of the tableView. Options include placing the searchBar in a navigation bar, or in a view above the tableView.

  • Replacing reloadData with one of the following approaches to avoid reloading the tableView header:

    • Use reloadSections:withRowAnimation: to reload a section of the table, or

    • Use beginUpdates endUpdates to animate changes for specific rows to be inserted or deleted.

3

What worked for me is to make the becomeFirstResponder call to happen after the reloadData one:

[self.tableView reloadData];
[self.searchBar becomeFirstResponder];

This is working on iOS 8.1.2, I didn't test it on other versions yet.

1

I had the same issues encountered above but for a different reason. My UISearchBar was within a cell at the top of the table. When typing, I would call to reload the UITableView and this was causing the search bar to lose focus - because the cell containing the search bar was one that was being reloaded.

The solution was to only reload the cells I needed. My search bar was in section 0, and all search results in section one. So a call like this ensured that only section 1 was reloaded, and the search bar did not lose focus.

NSIndexSet *section1 = [NSIndexSet indexSetWithIndex:1];
[self.tableView reloadSections:section1 withRowAnimation:UITableViewRowAnimationAutomatic];
Luke Smith
  • 1,218
  • 12
  • 17
0

When searchBar:textDidChange: is called, searchBar is the FirstResponder. There is no need to send it a becomeFirstResponder message.
Moreover, you do send becomeFirstResponder to self.searchBar, which might not be the same as the searchBar that is transferred to you during the searchBar:textDidChange: method call.
I suggest to delete [self.searchBar becomeFirstResponder]; and to check if your property self.searchBar is really linked to the searchBar object in the callback searchBar:textDidChange:.

Reinhard Männer
  • 14,022
  • 5
  • 54
  • 116