I have a search bar with a suggestions UITableView
that gets populated (using JSON services) as the user types. These service calls need to be made after a delay of 500ms of non-typing. If the user starts to type in this period of 500ms, the current call in the queue needs to be cancelled and the app has to wait another 500ms of non-activity before making another afterDelay
call. I know I have to use performSelector:withObject:afterDelay
in this entire situation, but I'm not able to get around with proper conditions. I tried using a bunch of bools but it just getting dirty... Any help?
I would use an NSTimer
instead of performSelector:withObject:afterDelay:
. Detect when the text changes in the UISearchBar
and reset the timer.
-(void)viewDidLoad {
search.delegate = self;
}
-(void)searchBar:(UISearchBar *)theSearchBar textDidChange:(NSString *)searchText {
[timer invalidate];
timer = [NSTimer scheduledTimerWithTimeInterval:0.5 target:self selector:@selector(callTheService) userInfo:nil repeats:NO];
}
How about this, assuming you're detecting typing in a UITextFieldDelegate
method:
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
[NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(sendNetworkRequest) object:nil];
[self performSelector:@selector(sendNetworkRequest) withObject:nil afterDelay:0.5];
return YES;
}
- (void)sendNetworkRequest
{
// Here immediately send the request
}
I like this appraoch to problems like these as it means I don't have to use an NSTimer
or keep track of any state of whether I'm waiting to see if more text is entered or not. Hope this helps! Let me know if you have any questions.
EDIT: Saw you're using a search bar instead. The principle is the same, just put the cancel/perform pairing in the appropriate UISearchBarDelegate
method.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With