8

I'm using the NSAttributedString UIKit Additions to draw an attributed string in a UIView. The problem I have is that despite using a value of NSWritingDirectionNatural for the baseWritingDirection property of my paragraph style, text always defaults to left-to-right.

Here's how I form the attributed string (simplified):

NSString *arabic = @"العاصمة الليبية لتأمينها تنفيذا لقرار المؤتمر الوطني العام. يأتي ذلك بعدما أعلن اللواء الليبي المتقاعد خليفة حفتر أنه طلب من المجلس الأعلى للقض الدولة حتى الانتخابات النيابية القادمة";

NSMutableParagraphStyle *paragraph = [[NSMutableParagraphStyle alloc] init];
paragraph.baseWritingDirection = NSWritingDirectionNatural;
paragraph.lineBreakMode = NSLineBreakByWordWrapping;

NSMutableDictionary *attributes = [[NSMutableDictionary alloc] init];
attributes[NSParagraphStyleAttributeName] = paragraph;

NSAttributedString *string = [[NSAttributedString alloc] 
                             initWithString:arabic 
                             attributes:attributes];

And here's how I draw the text:

- (void)drawRect:(CGRect)rect {
    [self.attributedText drawWithRect:rect 
                              options:NSStringDrawingUsesLineFragmentOrigin 
                              context:nil];
}

And yet it still flows from left to right:

screenshot

What am I missing?

Charles
  • 50,943
  • 13
  • 104
  • 142
jaredsinclair
  • 12,687
  • 5
  • 35
  • 56

3 Answers3

7

I don't believe the writing direction will be automatically set for you using baseWritingDirection unless you switch languages on the device:

"If you specify NSWritingDirectionNaturalDirection, the receiver resolves the writing direction to either NSWritingDirectionLeftToRight or NSWritingDirectionRightToLeft, depending on the direction for the user’s language preference setting."

For some reason the text you have still doesn't seem to work even with arabic selected without adding the language to your supported localizations. This character seemed to work without doing that for me: كتب

Also, it looks like Xcode reverses the characters in hardcoded arabic strings so that may be screwing with some of this copy and paste.

You can use agiletortoises's suggestion or NSLinguisticTagger's Language tag scheme to manually set the language.

Community
  • 1
  • 1
bjtitus
  • 4,231
  • 1
  • 27
  • 35
  • `NSWritingDirectionNatural` is documented as "Use the Unicode Bidi algorithm rules P2 and P3 to determine which direction to use." That sure sounds like it depends on the text. – Lily Ballard May 22 '14 at 17:37
  • Yep, this is so strange. It hearkens back to the old saw: *cache invalidation and naming things…* The name `NSWritingDirectionNatural` suggests that the drawing classes will introspect the string to determine an appropriate line direction. A more accurate name would be `NSWritingDirectionSystem`. – jaredsinclair Jun 09 '14 at 15:15
  • The workaround I will use is from @agiletortoise answer, as setting an explicit line direction will work regardless of the current system language direction. – jaredsinclair Jun 09 '14 at 15:16
4

I can't explain why it does not work the way you have it written, but I've been using a solution to explicitly set the direction based on known RTL languages, which used this as a starting point:

https://stackoverflow.com/a/16309559

Community
  • 1
  • 1
  • recommend everyone to check this link, the answer there for me, was exactly what I was looking for. I don't understand why this is not built-in NSString with some nice boolean property – user1105951 Apr 05 '15 at 11:15
0

No idea if this is related or not, but when I tested the right-to-left support in Auto Layout, it didn't work until I added a localization for that language (Arabic, Hebrew, etc) to the app.

Hollance
  • 2,958
  • 16
  • 15