阿拉伯语:

背景:阿拉伯语使用者占世界人口的6%,使用阿拉伯字母,为从右至左书写的文字,主要通行于18个阿拉伯国家及4个国际组织的官方语言。以阿拉伯语作为母语的人数超过2.6亿人。阿拉伯语在全球范围使用者总计目前已经突破4.4亿人。

语言特点:是由28个辅音字母和12个发音符号(不包括叠音符)组成的拼音文字。书写顺序从右往左横行书写,翻阅顺序也是由右往左。

左右的相互调换,使用系统提供的方法(RTL仅支持iOS9以上)

1.针对全部的UIView 使用镜像功能

[UIView appearance].semanticContentAttribute = UISemanticContentAttributeForceRightToLeft;
[UISearchBar appearance].semanticContentAttribute = UISemanticContentAttributeForceRightToLeft;
[[UINavigationBar appearance] setSemanticContentAttribute:UISemanticContentAttributeForceRightToLeft];

2.针对具体部分View使用

self.view.semanticContentAttribute = UISemanticContentAttributeForceRightToLeft;

3.针对xib、storyboard

Semantic 设置为spatial

前提: 使用 left right 或者 frame的情况下都是指定了具体的方向和坐标位置,系统不会进行调整,使用Leading和Trailing系统会自动调整。

判断当前方向:

[UIApplication sharedApplication].userInterfaceLayoutDirection

[UIView userInterfaceLayoutDirectionForSemanticContentAttribute:view.semanticContentAttribute]

view.effectiveUserInterfaceLayoutDirection

特殊控件:

1.collectionView

解决方案:修改CollectionViewFlowLayout

flipsHorizontallyInOppositeLayoutDirection是指开启 一个布尔值,指示水平坐标系是否在适当的时间自动翻转。 这个属性是默认关闭的 如果发生无法反转的话,我们需要这样打开。

flipsHorizontallyInOppositeLayoutDirection是readonly的,我们需要自定义layout,并重写getter方法。

2.tableView

header和cell不会改变textAlignment

文字

1.UIEdgeInsets

然而系统却不会自动帮我们将left和right调换。我们需要手动去适配它。

方法一:在需要的地方判断以下。

方法二:hook

2.TextAlignment(包括AttributeString的textAlignment)

方法一:

[[(NSMutableParagraphStyle *)paraStyle setAlignment:NSNaturalTextAlignment];

方法二:hook

3.双向文字

拉丁语和数字是始终LTR的,开发者需要自己适配。

情景一:固定文字,如Label。(demo)

我们的解决方式跟苹果推荐的一致,多语言拼接其他LTR字符。

情景二:文字输入,如TextField

WWDC 2013 Making Your App World-Ready: International Text > Bidirectional Text

setBaseWritingDirection:forRange:
UITextWritingDirectionNatural

苹果不建议修改。

交互

1.滑动返回:

navigation需要单独设置,解决方案是hook了UINavigationController的initWithNibName:bundle:,单独设置UINavigationController的view的semanticContentAttribute

2.UISwipeGestureRecognizer:

hook了UISwipeGestureRecognizer的setDirection:

图片

系统不会为我们自动做处理,大部分图片也不需要处理,只需要手动旋转一下类似箭头的图片即可。

方法一:系统提供了- (UIImage *)imageFlippedForRightToLeftLayoutDirection NS_AVAILABLE_IOS(9_0);

只有系统语言切换有用,应用内切换不生效,所以自己单独写方法

方法二:修改xcassets中对应图片资源的direction

方法三:使用Localize Resources

方法四:

- (NSImage *)flipImage:(NSImage *)image
{
   NSImage *existingImage = image;
   NSSize existingSize = [existingImage size];
   NSSize newSize = NSMakeSize(existingSize.width, existingSize.height);
   NSImage *flippedImage = [[[NSImage alloc] initWithSize:newSize] autorelease];
 
   [flippedImage lockFocus];
   [[NSGraphicsContext currentContext] setImageInterpolation:NSImageInterpolationHigh];
 
   NSAffineTransform *transform = [NSAffineTransform transform];
   [transform translateXBy:existingSize.width yBy:0];
   [transform scaleXBy:-1 yBy:1];
   [transform concat];
 
   [existingImage drawAtPoint:NSZeroPoint fromRect:NSMakeRect(0, 0, newSize.width, newSize.height) operation:NSCompositeSourceOver fraction:1.0];
 
   [flippedImage unlockFocus];
 
   return flippedImage;
}

哪些功能不需要适配RTL?

Types of controls and content that should not flip in a right-to-left language are:

  • Video controls and timeline indicators
  • Images, unless they communicate a sense of direction, such as arrows
  • Clocks
  • Music notes and sheet music(乐谱)
  • Graphs (x– and y–axes always appear in the same orientation)

toolbars RTL不生效,怎么办?

if ([NSApp userInterfaceLayoutDirection] == NSUserInterfaceLayoutDirectionRightToLeft) {
   NSArray *toolbarItems = [[self.toolbar items] copy];
   for (NSToolbarItem *item in toolbarItems) {
       [self.toolbar removeItemAtIndex:toolbarItems.count-1];
       [self.toolbar insertItemWithItemIdentifier:item.itemIdentifier atIndex:0];
   }
}

要点总结

1.尽量都使用约束来做UI,且不要用left和right,改用leading和trailing。

2.文字对齐如果是左右对齐的话,都使用NSNaturalTextAlignment。

3.多语言遇到拼接字符串的话,要谨慎。其他LTR语言中,如果是拼接字符串,第一个字符是RTL语言,会出现显示问题,应该使用localizedStringWithFormat(使用后,底层会去判断去除该字符之后的字符串的第一个字符)。

4.如果遇到需要适配排列方向的collectionView,提前自定义layout。

5.需要镜像的图片使用恰当的方法实现。

参考资料

RLT官方文档WWDC2015WWDC2016