Thanks to the help of those on SO, I have a great UISearchBar that filters my UITableView. There is one more feature that I'd like to add.
I would like the UISearchBar filter to ignore special characters like apostrophes, commas, dashes, etc... and to allow cells with text like "Jim's Event" or "Jims-Event" to still come up if the user types "Jims Event".
for (NSDictionary *item in listItems)
{
if ([scope isEqualToString:@"All"] || [[item objectForKey:@"type"]
isEqualToString:scope] || scope == nil)
{
NSStringCompareOptions opts = (NSCaseInsensitiveSearch|NSDiacriticInsensitiveSearch);
NSRange resultRange = [[item objectForKey:@"name"] rangeOfString:searchText
options:opts];
if (resultRange.location != NSNotFound) {
[filteredListItems addObject:item];
}
}
}
Anyone have any ideas? Thank you!
This one is a little tricky. The first solution that comes to mind is to strip any character that you deliberately don't want to match from both the search and item strings, then do the comparison. You can use NSCharacterSet instances to do that filtering:
// Use this method to filter all instances of unwanted characters from `str`
- (NSString *)string:(NSString *)str filteringCharactersInSet:(NSCharacterSet *)set {
return [[str componentsSeparatedByCharactersInSet:set]
componentsJoinedByString:@""];
}
// Then, in your search function....
NSCharacterSet *unwantedCharacters = [[NSCharacterSet alphanumericCharacterSet]
invertedSet];
NSString *strippedItemName = [self string:[item objectForKey:@"name"]
filteringCharactersInSet:unwantedCharacters];
NSString *strippedSearch = [self string:searchText
filteringCharactersInSet:unwantedCharacters];
Once you have the stripped strings, you can do your search, using strippedItemName
in place of [item objectForKey:@"name"]
and strippedSearch
in place of searchText
.
In your example, this would:
- Translate the search string "Jims Event" to "JimsEvent" (stripping the space)
- Translate an item "Jim's Event" to "JimsEvent" (stripping the apostrophe and space)
- Match the two, since they're the same string
You might consider stripping your search text of unwanted characters once, before you loop over item names, rather than redoing the same work every iteration of your loop. You can also filter more or fewer characters by using a set other than alphanumericCharacterSet
- take a look at the class reference for more.
Edit: we need to use a custom function to get rid of all characters in the given set. Just using -[NSString stringByTrimmingCharactersInSet:]
only filters from the ends of the string, not anywhere in the string. We get around that by splitting the original string on the unwanted characters (dropping them in the process), then rejoining the components with an empty string.