How do you detect that a UILabel contains a right-to-left language in Cocoa Touch?

cocoa-touch, objective-c, regex

Solution

This answer assumes that you are using ARC:

NSString *stringToTest = @"Some Foreign Language";

NSString *isoLangCode = (__bridge_transfer NSString*)CFStringTokenizerCopyBestStringLanguage((__bridge CFStringRef)stringToTest, CFRangeMake(0, stringToTest.length));

NSLocaleLanguageDirection direction = [NSLocale characterDirectionForLangauge:isoLangCode];

You can then use the NSLocale API's lineDirectionForLanguage: method to determine the languages line direction.

Problem

I am displaying user comments in two UILabels - one for the username and one for the message. Both labels have the same X,Y coordinate, but the message label is prepended with spaces equaling the width of the username. This technique helps me easily support multiline messages. A problem arises when users write Arabic messages. Arabic is a right to left language. This means, I must add spaces to the end of an Arabic string, not the beginning. As you can see in the screenshot below, I didn't make that distinction and the Arabic message ran into the username. So how do I detect that the text property (NSString) of a UILabel was written in a right-to-left language? Fail attempt 1: Regex I've tried using regexes, but the following function always returns false for every string, including Arabic. ``` @implementation UILabel (position) - (BOOL) containsArabic { NSError* error; NSRegularExpression* regex = [NSRegularExpression regularExpressionWithPattern:@"\p{Arabic}" options:0 error:&error ]; return error == nil && [regex numberOfMatchesInString:self.text options:0 range:NSMakeRange(0, self.text.length)] > 0; } @end ``` Fail attempt 2: NSLocale ``` - (BOOL) containsArabic { NSString *isoLangCode = (NSString*)CFStringTokenizerCopyBestStringLanguage( (CFStringRef)self.text, CFRangeMake( 0, self.text.length ) ); NSLocaleLanguageDirection direction = [NSLocale lineDirectionForLanguage:isoLangCode]; NSLog(@"++++++"); NSLog(@"%@", self.text); NSLog(@"%d", direction); return direction == NSLocaleLanguageDirectionRightToLeft; } ``` Output is useless: ``` 2012-05-28 10:59:11.454 [2110:707] MANCHESTER CITY VS MANCHESTER UNITED LIVE HD 2012-05-28 10:59:11.461 [2110:707] 0 2012-05-28 10:59:11.474 [2110:707] ++++++ 2012-05-28 10:59:11.477 [2110:707] tak 2012-05-28 10:59:11.484 [2110:707] 0 2012-05-28 10:59:11.511 [2110:707] ++++++ 2012-05-28 10:59:11.513 [2110:707] ونهارك سعيد 2012-05-28 10:59:11.520 [2110:707] 3 2012-05-28 10:59:11.704 [2110:707] ++++++ 2012-05-28 10:59:11.712 [2110:707] نهارك سعيد 2012-05-28 10:59:11.740 [2110:707] 3 2012-05-28 10:59:11.763 [2110:707] ++++++ 2012-05-28 10:59:11.767 [2110:707] i think i am close 2012-05-28 10:59:11.772 [2110:707] 3 ```

Original source