iOS冷门知识 -RightToLeft
苹果官方文档
在做国际化的时候你可能会碰到与我一样的问题,世界上有一群人使用习惯的方向与一般人是相反的(具体是怎么相反的,设置iphone的语言,选择阿拉伯文,你会发现一个新世界),因此,我们要根据他们的使用习惯对我们的app的UI布局变动以及字符变动。
PS:当你面试微信时可以很淡定地喷他们RightToLeft的适配做的如何糟糕,事实也的确如此,他们一部分的UI布局并没有实现标准的RightToLeft。
2016/6/04更正,测试的时候发现对RightToLeft理解有误,在iOS9及以上版本中苹果已经自动适配好RightToLeft,只要实现了leading和trailing两个约束,用户在切换到特定的语言环境下便自动切换到RightToLeft UI布局。文档中提供的方法大多是为了两种状况,一是开发者想要在LeftToRight环境下强制转换UI布局到RightToLeft(例如在中文环境下翻转UI布局),二是当存在具有方向性质的图片时(例如带有箭头图片的Button)提供开发者手动翻转button的API,因此,不要使用文章中提到的func isRightToleftLanuage(),建议使用最后一段代码的判断。
maps_rtl_mirroring_2x.png如上图所示,UI布局左右翻转,并且文字也有变动,具体文字……我不知道……安拉胡阿克巴?
在此,有个好消息和一个坏消息。
好消息是,苹果已经帮我们做好了UI布局变动的事项,只要你的app是建立在约束环境中,并且实现了Leading以及Trailing两个约束条件而不是Left和Right,那么,只要输入几句短短的代码就可以轻松不费力地完成整个UI布局的变动。(转换UI布局的判断大体上应该是判断用户语言环境是否为阿拉伯文,除了阿拉伯文外我似乎没见到需要RightToLeft的)
坏消息是……仅支持ios9及以上版本。
好的,我们先不要管iOS9以下版本的死活了,如果你想要全局实现UI布局变动那么就在AppDelegate中如此实现:
UIView.appearance().semanticContentAttribute = UISemanticContentAttribute.ForceRightToLeft
一行代码轻松实现左右转换。
当然,这样是不够的,我们需要的是根据不同语言环境选择RightToLeft或者LeftToRight,这么写如何?
if #available(iOS 9.0, *) {
if isRightToleftLanuage(){
UIView.appearance().semanticContentAttribute = UISemanticContentAttribute.ForceRightToLeft
}else{
UIView.appearance().semanticContentAttribute = UISemanticContentAttribute.ForceLeftToRight
}
} else {
// Fallback on earlier versions
}
}
代码大体思路很简单,判断用户是否为iOS9环境,若是则进入下一步判断,判断用户是否为RightToLeft习惯的人群,这部分判断我是根据语言环境写的。
值得一提的是,在Xcode环境下,若你设置的支持版本在ios9以上 前面判断ios版本的代码便不会出现,若设置的支持版本有低于IOS9版本的,则判断代码会自动填充。
func isRightToleftLanuage()->(Bool){
let defaults = NSUserDefaults.standardUserDefaults()
let languages = (defaults.objectForKey("AppleLanguages")) as? [String]
guard let l = languages?.first else{
return false
}
if l.hasPrefix("ar"){
return true
}
return false
}
这样就能实现全局的UI布局变动。
有的人会问了,如果我不想实现全局变动呢?Just One VC!
//设置单一界面的UI布局,这里使用了一个vc
self.view.semanticContentAttribute = .ForceRightToLeft
//苹果同样提供了判断当前用户阅读环境的方法
if UIView.userInterfaceLayoutDirectionForSemanticContentAttribute(view.semanticContentAttribute) == UIUserInterfaceLayoutDirection.RightToLeft {
print("haha")
}else{
print("wuwu")
}
需要注意的是如果你的app中存在UITextField时需要手动实现文本内容对齐方式的RightToLeft。
个人的解决办法是写了一个BaseTextField,然后用isRightToleftLanuage()直接在初始化方法中改变它的Alignment,比较奇怪的是直接修改StoryBoard中的TextField的时候若使用了Secure Text Entry文本加密并置Alignment为None时可以实现TextField的RightToLeft适配,但取消Text Entry文本加密却会无法实现自动适配,不知道是我个人原因还是有其它因素影响。
至于字符串的适配,就我个人观察而言,似乎在实现国际化的阿拉伯文本时字符串已经自适配了,个人情况是这样的,不知道有没有朋友的情况和我不一样。