Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Non US characters in section headers for a UITableView

I have added a section list for a simple Core Data iPhone app.

I followed this so question to create it - How to use the first character as a section name but my list also contain items starting with characters outside A-Z, specially Å,Ä and Ö used here in Sweden.

The problem now is that when the table view shows the section list the three last characters are drawn wrong. See image below

              • alt text http://img.skitch.com/20100130-jkt6e55pgyjwptgix1q8mwt7md.jpg

It seems like my best option right now is to let those items be sorted under 'Z'

if ([letter isEqual:@"Å"] ||
    [letter isEqual:@"Ä"] ||
    [letter isEqual:@"Ö"]) 
    letter = @"Z";

Someone that have figured this one out?

And while I'm at it... 'Å', 'Ä' and 'Ö' should be sorted in that order but are sorted as 'Ä', 'Å' and 'Ö' by Core Data NSSortDescriptor. I have tried to set set the selector to localizedCaseInsensitiveCompare: but that gives a out of order section name 'Ä. Objects must be sorted by section name' error. Seen that too?

like image 202
epatel Avatar asked Jan 30 '10 12:01

epatel


1 Answers

So I could not let go of this one and found the following:

What you need to do in this case is called 'Unicode Normalization Form D'. It is more explained in http://unicode.org/reports/tr15/ (warning, long and dry document)

Here is a function that does the decomposition and then filters out all diacritics. You can use this to convert Äpple to Apple and then use the first letter to build an index.

- (NSString*) decomposeAndFilterString: (NSString*) string
{
    NSMutableString *decomposedString = [[string decomposedStringWithCanonicalMapping] mutableCopy];
    NSCharacterSet *nonBaseSet = [NSCharacterSet nonBaseCharacterSet];
    NSRange range = NSMakeRange([decomposedString length], 0);

    while (range.location > 0) {
        range = [decomposedString rangeOfCharacterFromSet:nonBaseSet
            options:NSBackwardsSearch range:NSMakeRange(0, range.location)];
        if (range.length == 0) {
            break;
        }
        [decomposedString deleteCharactersInRange:range];
    }

    return [decomposedString autorelease];
}

(I found this code on a mailing list, forgot the source, but I took it and fixed it up a little)

like image 76
Stefan Arentz Avatar answered Oct 05 '22 07:10

Stefan Arentz