When performing costly tasks that are triggered by user input it is sensible to have a small pause before executing the task to ensure that the user has finished inputing their data. This small pause prevents a request being made for each key press. An example of this is the search function in the App Store app. The app waits for about half a second after each key press before executing the search. It is possible to achieve this by using NSTimer
s. However, an easier way is to use performSelector:withObject:afterDelay:
and cancelPreviousPerformRequestsWithTarget:selector:object:
. Here’s how:
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
//because the view can be unloaded we must store all data so that its state can be restored in viewDidLoad
self.searchQuery = [textField.text stringByReplacingCharactersInRange:range withString:string];
SEL fetchSearchResults = @selector(fetchSearchResults);
//cancel the previous search request
[[self class] cancelPreviousPerformRequestsWithTarget:self selector:fetchSearchResults object:nil];
//perform the search in a seconds time. If the user enters addition data then this search will be cancelled by the previous line
[self performSelector:fetchSearchResults withObject:nil afterDelay:1];
return YES;
}
-(void)fetchSearchResults
{
NSLog(@"performing search");
//...
}