Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

RagingGoat

macrumors 6502
Original poster
Jun 21, 2010
308
15
I have a search bar on my map view that allows the user to search for the name (annotation title) or address (annotation subtitle). I have it working just fine if the user types in the entire title or subtitle but I'm trying to have it so the user only has to type part of the name or address. For example, there is an annotation for Cates Farm. I'd like the user to be able to just type in cates and have it find the annotation. The way I have it set up not only just finds the last title in the array, but it runs slowly. Any help or suggestions?

Here is my code. The lines I've commented out are from where I had it working if the user types the entire title or subtitle.

Code:
- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar
{
    id<MKAnnotation> ann;
    NSString *searchText = [searchBar text];
    NSString *annTitle = ann.title;
    NSString *annSubtitle = ann.subtitle;
    NSRange titleRange = [annTitle rangeOfString:searchText options:NSCaseInsensitiveSearch];
    NSRange subtitleRange = [annSubtitle rangeOfString:searchText options:NSCaseInsensitiveSearch];
    
    for (int i = 0; i < [marketLocations count]; i++)
    {
        for (ann in marketLocations)
        {
            // if ([ann.title isEqualToString:[searchBar text]])
            if (titleRange.location != NSNotFound)
            {
                [worldView selectAnnotation:ann animated:YES];
            }
            // else if ([ann.subtitle isEqualToString:[searchBar text]])
            else if (subtitleRange.location != NSNotFound)
            {
                [worldView selectAnnotation:ann animated:YES];
            }
        }
    }
    
    [searchBar resignFirstResponder];
}
 
I have a search bar on my map view that allows the user to search for the name (annotation title) or address (annotation subtitle). I have it working just fine if the user types in the entire title or subtitle but I'm trying to have it so the user only has to type part of the name or address. For example, there is an annotation for Cates Farm. I'd like the user to be able to just type in cates and have it find the annotation. The way I have it set up not only just finds the last title in the array, but it runs slowly. Any help or suggestions?

Here is my code. The lines I've commented out are from where I had it working if the user types the entire title or subtitle.

Code:
- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar
{
    id<MKAnnotation> ann;
    NSString *searchText = [searchBar text];
    NSString *annTitle = ann.title;
    NSString *annSubtitle = ann.subtitle;
    NSRange titleRange = [annTitle rangeOfString:searchText options:NSCaseInsensitiveSearch];
    NSRange subtitleRange = [annSubtitle rangeOfString:searchText options: NSCaseInsensitiveSearch];
    
    for (int i = 0; i < [marketLocations count]; i++)
    {
        for (ann in marketLocations)
        {
            // if ([ann.title isEqualToString:[searchBar text]])
            if (titleRange.location != NSNotFound)
            {
                [worldView selectAnnotation:ann animated:YES];
            }
            // else if ([ann.subtitle isEqualToString:[searchBar text]])
            else if (subtitleRange.location != NSNotFound)
            {
                [worldView selectAnnotation:ann animated:YES];
            }
        }
    }
    
    [searchBar resignFirstResponder];
}

Your code has lots of problems.

When the user enters a string to search for, you should fetch that string and save it in a local variable. Your code is doing some stuff with finding the range of the user-entered text in an annotation "ann" that's stored in a local variable, but you never put anything in that variable. That code does not belong there.

Then you should probably use the NSArray method indexOfObjectPassingTest to test find an annotation that contains that substring. If you find a match in your test block you should set stop to YES and return the index of the object.

You should only select the annotation once the search is complete.

So:

  1. Fetch the user's search text in searchText, like you're doing.
  2. Write code using indexOfObjectPassingTest that uses rangeOfString with the NSCaseInsensitiveSearch option to look for matches in the title and subtitle of each annotation, and if it finds one, have the block set stop to true and return the index of that item.
  3. After the call to indexOfObjectPassingTest, if the result != NSNotFound, then select that annotation.
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.