views:

344

answers:

1

I have a UITableView containing names that I would like to group (and sort) by the first letter (similar to the Address Book application). I am currently able to match any section ('A'-'Z') using:

// Sections is an array of strings "{search}" and "A" to "Z" and "#".
NSString *pattern = [self.sections objectAtIndex:section];
NSPredicate *predicate = nil;

// Ignore search pattern.
if ([pattern isEqualToString:@"{search}"]) return nil;

// Non-Alpha and Non-Diacritic-Alpha (?).
if ([pattern isEqualToString:@"#"]);

// Default case (use case and diacritic insensitivity).
if (!predicate) predicate = [NSPredicate predicateWithFormat:@"name beginswith[cd] %@", pattern];

// Return filtered results.
return [self.friends filteredArrayUsingPredicate:predicate];

However, matching for the '#' eludes me. I tried constructing a REGEX match using:

[NSPredicate predicateWithFormat:@"name matches '[^a-zA-Z].*'"];

But this fails for diacritic-alpha (duplicate rows appear). Any ideas would be greatly appreciated! Thanks.

+2  A: 

I typically use UILocalizedIndexedCollation and a custom NSArray category to deal with this. I also have a wrapper (decorator) for UILocalizedIndexedCollation that will include the search symbol and handle the offsets for this for you.

The implementation of my NSArray category is here: http://gist.github.com/375409

So, given an array of objects objects with a name property, I would create an indexed array like so:

UILocalizedIndexedCollation *collation = [UILocalizedIndexedCollation currentCollation];
NSArray *indexedObjects = [objects indexUsingCollation:collation withSelector:@selector(name)]; // returns an array of arrays

Its important to note that UILocalizedIndexedCollation already deals with the logic of indexing and grouping your objects in a localized manner, so there is no need to reinvent the wheel here.

My collation decorator that deals with the search icon can be found in this github gist.

A more detailed tutorial on using it can be found on my blog.

In this case, you would simply pass in an instance of my collation wrapper instead of UILocalizedIndexedCollation in the example above.

Luke Redpath
Thanks for the quick reply Luke! I am just taking a look through everything now and doing fixes to see if it works! Cheers.
Kevin Sylvestre