Execute code once in SearchBar textDidChange delegate

668 views Asked by At

I want to execute certain code (only once) when user enters three or more character in searchbar. I have used below code :

 - (void) searchBar:(UISearchBar *)theSearchBar textDidChange:(NSString *)searchText {

        if ([searchText length] >= 3) { 

         [self performSelector:@selector(searchBarSearchButtonClicked:) withObject:theSearchBar afterDelay:3.0];    
        }    
   }

The problem in using above code is it executes number of times greater than three. Eg. If five character is entered in searchbar then it executes for three times (desired only once).

How to achieve this? Sure +1 for correct answer.

3

There are 3 answers

0
Jayprakash Dubey On BEST ANSWER

I found solution by using NSTimer. Below is snippet :

- (void) searchBar:(UISearchBar *)theSearchBar textDidChange:(NSString *)searchText {

    [timer invalidate];
    timer = nil;    
    ...

    if ([searchText length] >= 3) { 

       timer = [NSTimer scheduledTimerWithTimeInterval: 3.0 target: self
             selector: @selector(SearchBarProxyCall) userInfo:nil repeats: NO];   
    }
}

- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar {
    [timer invalidate];
    timer = nil;

    ...
}

-(void)SearchBarProxyCall { 
    [self searchBarSearchButtonClicked:searchbar];
}
0
Hemang On
#define kSilentTag 0
#define kViolentTag 1

- (BOOL)searchBar:(UISearchBar *)searchBar shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text {
    NSString *newString = [searchBar.text stringByReplacingCharactersInRange:range withString:text];
    if ([newString length] >= 3) {
        if(searchBar.tag == kSilentTag) {
            searchBar.tag = kViolentTag;
            [NSRunLoop cancelPreviousPerformRequestsWithTarget:self selector:@selector(searchBarSearchButtonClicked:) object:searchBar];
            [self performSelector:@selector(searchBarSearchButtonClicked:) withObject:searchBar afterDelay:3.0];
        }
    }else{
        searchBar.tag = kSilentTag;
    }
    return YES;
}

Okey, this is the final update to this answer, I don't like to take BOOLs so I made a define tag to achieve this, kSilentTag should be anything but don't matched to kViolentTag, also it should be your default tag for UISearchBar.

Important, at any point, if you're resetting your search bar, (means emptying it) just make sure to change its tag to kSilentTag back.

Suggestion, you've set 3.0 time interval to perform selector, you should set it some less (may be 1.0) because, user will certainly feel WHATs going on!! (like we felt on WindowsXP PCs before)? ^_^

2
Agarathi On

The below code will help you. It worked for me.

- (BOOL)searchBar:(UISearchBar *)searchBar shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text
{
    if ([searchBar text].length ==2) {
        [self performSelector:@selector(searchBarSearchButtonClicked:) withObject:searchBar afterDelay:3.0];
    }
    return YES;
}

-(void)searchBarSearchButtonClicked:(UISearchBar *)searchBar
{
    NSLog(@"Third text Entered");
}