I have implemented a UITableView with search bar (and search display) - all works fine, but the table results do not get updated until the search bar cancel button is tapped.
Delegate methods:
- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar {
// asynchronous request with [self.tableView reloadData] in the connectionDidFinishLoading
[self getProductData:searchBar.text];
[searchBar resignFirstResponder];
[self.tableView reloadData];
}
- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText {
}
- (void)searchBarCancelButtonClicked:(UISearchBar *)searchBar {
}
- (void)searchBarTextDidBeginEditing:(UISearchBar *)searchBar {
}
- (void)searchBarTextDidEndEditing:(UISearchBar *)searchBar {
}
- (BOOL)searchBarShouldEndEditing:(UISearchBar *)searchBar {
return YES;
}
Do I need to call a delegate method after receiving the data from the server? Or should I make the request synchronous?
Thanks
edit: I tried with a synchronous request and it still does not work!
Resolved this issue by adding this code to the end of my getProductData method:
[[[self searchDisplayController] searchResultsTableView] performSelectorOnMainThread:#selector(reloadData) withObject:nil waitUntilDone:NO];
I think you have to implement:
- (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString
and return YES
See the TableSearch sample code
Please try something like this:
- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText {
[self getProductData:searchText];
[self.tableView reloadData];
}
Related
I want to show the searchResultsTableView when my searchBar is selected. I have tried this:
- (void) searchDisplayControllerWillBeginSearch:(UISearchDisplayController *)controller {
[self.searchDisplayController.searchResultsTableView reloadData];
[self.searchDisplayController setActive:YES animated:YES];
}
and this:
- (void) searchDisplayControllerWillBeginSearch:(UISearchDisplayController *)controller {
[self.searchDisplayController setActive:YES animated:YES];
}
Neither works. In my numberOfRowsInSection method, I do have rows in the array, but the searchResultsTableView does not show until I start typing. Any thoughts? Thanks!
Try to set your searchdisplaycontroller to active in the following UISearchBarDelegate method
- (void)searchBarTextDidBeginEditing:(UISearchBar *)searchBar;
This is really simple, though still driving my nuts. I have a uitableview where I am trying to animate transition in and out of editing mode. This is what I took from an example that I have seen. It does do the job, but without the animation.
Any thoughts?
- (IBAction) EditTable:(id)sender
{
if(self.editing)
{
[super setEditing:NO animated:YES];
[tblSimpleTable setEditing:NO animated:YES];
[tblSimpleTable reloadData];
[self.navigationItem.leftBarButtonItem setTitle:#"Edit"];
[self.navigationItem.leftBarButtonItem setStyle:UIBarButtonItemStylePlain];
}
else
{
[super setEditing:YES animated:YES];
[tblSimpleTable setEditing:YES animated:YES];
[tblSimpleTable reloadData];
[self.navigationItem.leftBarButtonItem setTitle:#"Done"];
[self.navigationItem.leftBarButtonItem setStyle:UIBarButtonItemStyleDone];
}
}
PS: I am also not sure why I need this line: [super setEditing:NO animated:YES]; but things just dont seem to work at all without it. I just saw a few examples online that dont do that.
Thanks!
Maybe you should not reloadData when set editing property.
BTW, What's your "super" class? Normally you don't have to invoke [super setEditing:YES animated:YES];
Is it only the button that isn't animating properly? Either way you should probably be using super.editButtonItem instead of your own; it's animated and just setting the text and style like that (I believe) isn't. As far as calling the super, are you overriding one of the editing methods and not calling the super method from within there? And xuzhes's answer about the reloadData is, I believe, correct as well.
Try this:
#Implementation YourViewController // This can (should) be a subclass of UITableViewController to make your life easier
- (void)viewDidLoad {
[super viewDidLoad];
self.navigationItem.rightBarButtonItem = self.editButtonItem; // Automatically calls setEditing:animated: and changes itself to "Edit"/"Done" between presses
}
- (void)setEditing:(BOOL)editing animated:(BOOL)animated {
[super setEditing:editing animated:animated];
if (editing == YES) {
// Do stuff here
} else {
// Do stuff here
}
// Reload all sections of the table view
// THIS IS THE PART YOU'RE INTERESTED IN
NSRange range = NSMakeRange(0,[self.tableView numberOfSections]);
NSIndexSet *indexSet = [NSIndexSet indexSetWithIndexesInRange:range];
[self.tableView reloadSections:indexSet withRowAnimation:UITableViewRowAnimationAutomatic];
}
Check out the documentation for comments on the methods from Apple :)
I have a table with 3 UITextFields added to the content views of cells (1 row per section). I have a 4th section that I insert so that I can scroll the particular field to be above the keyboard.
The problem I have (on the iPad only) is that when one of the text fields has firstResponder, it does not relinquish it when user taps on another field. Are there differences in the responder chain on an ipad? In the bellow code for my view controllers UITextFieldDelegate - textFieldShouldEndEditing does not get called when touching another field. Pressing the done button works as expected (unless another field has been touched).
Anything wrong with the code bellow?
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField {
if (!_editing++) {
[self.tableView insertSections:[NSIndexSet indexSetWithIndex:4] withRowAnimation:UITableViewRowAnimationNone];
}
// scroll to section number in the text fields tag
[self.tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:textField.tag] atScrollPosition:UITableViewScrollPositionTop animated:YES];
return YES;
}
- (void) textFieldDidBeginEditing:(UITextField *)textField {
self.navigationItem.rightBarButtonItem = [[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:textField action:#selector(resignFirstResponder)] autorelease];
}
- (BOOL)textFieldShouldEndEditing:(UITextField *)textField {
if (_editing-- == 1) {
//
[self.tableView deleteSections:[NSIndexSet indexSetWithIndex:4] withRowAnimation:UITableViewRowAnimationNone];
}
self.navigationItem.rightBarButtonItem = nil;
// do something with the text here...
return YES;
}
OK, i have found a satisfactory workaround, it seems allowing the run loop to execute before the request to animate removing a section fixes the problem. I guess this is an apple bug? For anyone else worried about this issue - i was running iOS3.2.1 on the iPad.
- (BOOL)textFieldShouldEndEditing:(UITextField *)textField {
if (_editing == 1) {
[self performSelector:#selector(hideFinalSection) withObject:nil afterDelay:0.0f];
}
else {
_editing--;
}
self.navigationItem.rightBarButtonItem = nil;
// do something with the text here...
return YES;
}
- (void) hideFinalSection {
if (!(--_editing)) {
[self.tableView deleteSections:[NSIndexSet indexSetWithIndex:4] withRowAnimation:UITableViewRowAnimationNone];
}
}
I have a very basic UITableView with an attached UISearchBar, and here's the flow of what happens
UITableView is empty, user taps UISearchBar, and brings up keyboard.
Once the user taps the Search button
- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar {
[searchBar resignFirstResponder]; //move the keyboard out of the way
//Code....
}
Works just fine, and moves the keyboard out of the way, and populates the UITableView.
The problem is any subsequent search attempts.
The same steps as before occur, however the keyboard is never dismissed. I have a feeling something else is becoming the responder, I just need a little clarity to understand what is actually occurring.
Without seeing your code it is difficult to guess. However, if you include:
[self.view endEditing:YES];
all views will resign first responder.
Not perfect but did work for my case. Will not work without dispatch_after
- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText {
if (!searchText.length) {
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[searchBar resignFirstResponder];
});
}
}
- (void)searchBarTextDidEndEditing:(UISearchBar *)searchBar {
[self performSearchWithString:searchBar.text];
[searchBar resignFirstResponder];
}
I'm implementing a search bar on my table, which should be pretty straight forward. I've got these:
- (void)searchBarTextDidBeginEditing:(UISearchBar *)theSearchBar {
NSLog(#"searchBarTextDidBeginEditing");
}
- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText {
NSLog(#"The search text is: %#", searchText);
}
- (void)searchBarTextDidEndEditing:(UISearchBar *)theSearchBar {
NSLog(#"searchBarTextDidEndEditing");
[theSearchBar resignFirstResponder];
}
And searchBarTextDidBeginEditing fires, and I get that message in my log, but when I tap outside the search bar, above the keyboard, I don't get the searchBarTextDidEndEditing event so I can't make the keyboard disappear – the message doesn't even appear in the log.
The textDidChange is working, so it's just searchBarTextDidBeginEditing that isn't.
Any ideas? Thanks!!
Even i faced the same problem.
Please find with the solution below
Implement Below methods
1.searchBarTextDidEndEditing
2.searchBarSearchButtonClicked
and make sure you [UISearchchbar resignfirstresponder] in the second method mentioned above
Once I implemented searchBarSearchButtonClicked that solved it for me.
The method
(void)searchBarTextDidEndEditing:(UISearchBar *)searchBar
is only called when [searchBar resignFirstResponder] is called.
The best place to call [searchBar resignFirstResponder] is in the method
(void)searchBarSearchButtonClicked:(UISearchBar *)searchBar
In swift:
(void)searchBarTextDidEndEditing:(UISearchBar *)searchBar;
(void)searchBarSearchButtonClicked:(UISearchBar *)searchBar;