本文档针对以下问题进行了说明:
- 系统方法解读
- 如何进行国际化配置
- 应用名称AppName国际化
- 文本国际化
- 图片国际化
- App内语言切换设计
- Xib/Storyboard国际化
- 批量处理
- 国际化调试、测试
系统方法解读
NSLocalizedString(_ key: String, tableName: String? = default, bundle: Bundle = default, value: String = default, comment: String) -> String
key: 需要本地化的字符串对应的键值
tableName: 指定在相应的lproj文件中的tableName.string文件中查找文字资源,如果传入
null,则在Localizable.strings中查找
bundle: 语言文件所在的bundle
value: 默认值,如果本地化资源文件中没有找到对应的 key 则返回这个值
commit: 可传nil,是对key的注释
国际化配置
选中project->Info->Localizations,然后点击”+”,添加需要国际化/本地化的语言
应用名称AppName国际化
创建名称为InfoPlist的文件,选中InfoPlist.strings,在Xcode右侧点击Localize,选择需要本地化的语言
在各语言InfoPlist.strings中设置AppName
1 | CFBundleDisplayName = "Localizable App Name"; |
AppName国际化即已完成
字符串文本国际化
创建名称为Localizable的文件,选中Localizable.strings,在Xcode右侧点击Localize,选择需要本地化的语言
在Localizable.strings下对应的文件中,分别以Key-Value的形式,为代码中每一个需要本地化的字符串赋值
字符串国际化即已完成
图片国际化
有两种方式,第一种方式和国际化字符串一样,在Localizable.string中添加不同语言下对应的图片,调用时根据LocalizedString获取相应的image名称,获取图片。
第二种方式,是对图片进行Localize,大量的文章都说可以通过这种方式,经过多次尝试,始终获取不到此图片,还正在解决中…
App内语言切换
App内语言切换有两种实现方法:
切换语言时发送通知,所有的UI控件监听通知,然后刷新UI,类似于新浪微博实现,对于已有项目进行处理时较复杂
切换语言时,刷新keyWindow的rootViewController,类似微信的做法
针对刷新rootViewController这种,有以下两种设计思路:
方案一与方案二的区别在于:方案二不能在xib中对文本直接赋值,只能通过代码,因为在xib赋值时无法指定bundle,导致应用内语言切换时xib不生效
也因此有了方案一,利用runtime机制,自定义一个继承自NSBundle的子类,我们称它为CustomBundle,在运行时利用object_setClass将NSBundle替换为CustomBundle
在这个CustomBundle中重写上面的那个localizedStringForKey方法,然后在这个重写的方法里拦截系统的调用。这个LanguageBundle的作用如下:
替换NSBundle,让原本是localizedStringForKey的调用者的NSBundle,换为了LanguageBundle
在调用到localizedStringForKey的时候,可以对其实现高度定制,同时又可以让其父类NSBundle依旧执行该方法,只需super调用即可通过把NSBundle.mainBundle()替换成当前语言的bundle的方式来支持xib。
可根据项目的实际情况,如果都使用代码来为控件赋值的时候,建议使用方案二。
Xib/Storyboard国际化
选中xib/Storyboard文件,在Xcode右侧点击Localize,选择需要本地化的语言,在string文件中,给各语言环境下的控件进行赋值
关于xib、storyboard中,国际化的key是一次性生成的,如果存在增加新控件时,需要重新生成,针对这个问题,添加脚本
1 |
|
批量处理
####项目中文批量生成到Localizable.strings
针对已有项目,如果逐个文件进行替换无非要花费大量的时间,运用以下方法可进行批量替换
Command+Shift+F,进入全局搜索引擎,切换为Replace模式,并把匹配模式改为Regular Expression
在搜索条件里输入(@”[“][\u4E00-\u9FA5]+[“\n]?”),在下面替换内容里输入NSLocalizedString($1, nil)
点击Replace All,即可完成替换。
cd 工程目录
mkdir en.lproj
mkdir zh-Hans.lproj
find . -name .m | xargs genstrings -o en.lproj
find . -name .m | xargs genstrings -o zh-Hans.lproj
此时,en.lproj和zh-Hans.lproj文件夹中就有了相应的Localizable.string文件
国际化调试
在国际化测试时,可以通过在Edit Scheme中选择特定语言。