阿拉伯语:
背景:阿拉伯语使用者占世界人口的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.需要镜像的图片使用恰当的方法实现。
参考资料