一、国际化(本地化)
国际化又称本地化,一句话解释也就是说:用户设置不同的手机系统语言,您的APP也分别适配不同的语言。
二、本地化类型
1、首先创建项目工程(大家都懂跳过)
2、你需要告诉我您需要做哪些国家(语言)的国际化 —— 添加本地化语言
选中project->Info->Localizations,然后点击"+",添加需要国际化/本地化的语言,如下图(默认需要勾选Use Base Internationalization):
备注:“zh-Hans”和“zh-Hant”是简体中文和繁体中文的缩写。这是标准的缩写。H可大写也可小写。"en"是英语的缩写。ko是韩语的缩写,fr是法语的缩写。其他语言请百度或Google各国语言缩写即可查询。
(一)、应用名称本地化
应用名称本地化—— 同一个APP应用不同的语言环境对应不同的名称。例如:微信(中文)—— weChat(英文)。
1、找到项目中Supporting Files文件,选中Info.plist,右键添加新文件(或按下键盘上的command + N),选择Strings File(iOS->Resource->Strings File)新建一个infoPlist.strings文件
2、选中InfoPlist.strings,在Xcode的File inspection(Xcode右侧文件检查器)中点击Localize,目的是选择我们需要本地化的语言,如下图:
注意:在点击Localize之前,一定要保证我们已经添加了需要本地化的语言
3、接下来,勾选French、Chinese(zh-Hans)、Chinese(zh-Hant)、Korean,如下图:
4、Xcode左侧的InfoPlist.stirings左侧多了一个箭头,点击箭头可以展开,InfoPlist.strings文件下包含了English、French、Chinese(Simplified)、Chinese(Traditional)、Korean这五种语言的文件。
在程序启动时,会根据操作系统设置的语言,自动加载InfoPlist.strings文件下对应的语言文件,然后显示应用程序的名字。
5、在不同的strings文件中设置不同的APP名称即可,格式为key = value(CFBundleDisplayName = "App名称";)
例如在InfoPlist.strings(English)中加入如下代码:
CFBundleDisplayName = “weChat”;
例如在InfoPlist.strings(French)中加入如下代码:
CFBundleDisplayName = “Lettre datée du”;
例如在InfoPlist.strings(Simplified)中加入如下代码:
CFBundleDisplayName = “微信”;
例如在InfoPlist.strings(Traditional)中加入如下代码:
CFBundleDisplayName = “微信”;
例如在InfoPlist.strings(Korean)中加入如下代码:
CFBundleDisplayName = “미크롱 편지”;
6、结束了你懂得,是不是很简单。
(二)、APP中代码字符串本地化
字符串本地化——APP里面不同的语言环境显示不同的语言。例如:个人中心(中文)——Personal center(英文)
字符串本地化步骤和APP应用名称本地化基本上相同唯一不同的地方在于——文件名称
文件名必须是Localizable.strings
文件名必须是Localizable.strings
文件名必须是Localizable.strings
重要的事情说三遍
在这里我只说使用方法:利用Foundation框架自带的NSLocalizedString(key, comment)这个宏根据Key获取对应的字符串,然后赋值给代码中的字符串。
// NSLocalizedString(key,comment) 本质
// NSlocalizeString 第一个参数是内容,根据第一个参数去对应语言的文件中取对应的字符串,第二个参数将会转化为字符串文件里的注释,可以传nil,也可以传空字符串@""。#defineNSLocalizedString(key,comment) [[NSBundle mainBundle] localizedStringForKey:(key)value:@""table:nil]
(三)、APP中图片本地化(俩种方式)
方式一:和本地化代码中的字符串一样,通过NSLocalizedString(key,comment)来获取相应的字符串,然后根据这个字符串再获取图片。
方式二
1、导入图片(这个很简单吧,不用我说了哦亲)。
2、同样点击Localize如下图:
3、在en.Iproj文件和zh-Hans.Iproj文件中分别添加一个名字为icon.png的图片然后加载到项目中。
4、利用NSLocalizedString调用图片,系统会根据语言自动加载对应的图片的。
(四)、storyBoard/Xib文件本地化(不建议使用)
首先我们需要创建一个英文的storyBoard/xib文件,在 en.lproj 文件下。然后,需要使用命令行来操作:
1. 将.storyBoard/ .xib文件 中的文字提取,另存为 .strings文件。
ibtool --generate-strings-file MainViewController.strings MainViewController.xib
2. 将 MainViewController.strings 拷贝到 zh-Hans.lproj 目录下,然后汉化该文件中的文字
3. 执行命令,根据英文的 .storyBoard/ .xib文件 和 .strings汉化文件 生成一个汉化后的 .storyBoard/ .xib 文件
ibtool --strings-file zh-Hans.lproj/MainViewController.strings --write zh-Hans.lproj/MainViewController.xib en.lproj/MainViewController.xib
4. 将生成的这个.storyBoard/ .xib 文件添加到项目中的 zh-Hans.lproj 分组下,注意要选择 Add to targets
5. 选择 File -> Info -> Localization 为对应的语言
至此,storyBoard/ xibxib文件的汉化已经完成。
三、本地化中的坑——您跳过了吗?
(一)、iOS8之后国际化语言混乱
iOS8以后,有些国际化的app,界面也突然变成了中文,但他们系统语言不是中文,是法文俄文日文等,伊书只支持中文跟英文,在不支持系统所用语言的时候,理应会自动选用英文,不知为什么会选成了中文,经过艰难困苦的重重排查,终于找到原因,知道了iOS多语言备选的规则。
主要有两个影响因素,一是CFBundleDevelopmentRegion(Info.plist的一个字段),二是iOS8新增的系统首选语言列表:
在iOS7及之前版本,系统只能设置一种语言,如果APP不支持系统设置的语言,选用备选语言的规则是:
1.如果APP支持英文,直接选择英文。
2.如果APP不支持英文,随机挑选一个。
举个例子,APP支持中文跟英文,当系统语言是不是中文或英文时,都会选择英文。若APP支持中文跟法文,系统语言不是中文或法文,将会随机挑选一个。
从iOS8开始,系统语言可以设置一个语言列表,会根据这个语言列表的排序选用备选语言,规则就变了:
1.如果APP支持的语言在系统语言列表里有,优先选择列表上排序靠前的语言。
2.如果APP支持的语言没在系统语言列表上,按CFBundleDevelopmentRegion的值选择,无论APP是否支持英文,英文不再是默认的备选语言。
举个例子,APP支持中文跟英文,CFBundleDevelopmentRegion的值是中文,当系统语言列表是[法文]或[法文,中文]时,会选择中文,系统语言列表是[法文,英文]时,会选择英文。
苹果在语言方面似乎有不少bug,调试过程中出现不少坑爹的事,例如改变增删语言文件一定要clean工程否则不生效,iOS8模拟器不认CFBundleDevelopmentRegion的值,真机才认,再加上一开始不知道iOS8系统语言变成列表这事,把我迷惑得费了大量时间。总而言之,若要国际化,让APP支持英文,CFBundleDevelopmentRegion填英文,应该万无一失。
(二)、多语言环境下格式化时间字符串,阿拉伯等部分国家无法正确显示阿拉伯数字。
首先给你普及一个常识:阿拉伯语不用阿拉伯数字显示时间 —— 这就是造成问题的原因
解决办法:NSLocale类
NSLocale 类返回本地化信息,主要体现在"语言"和"格式"这两个设置上面
1、NSLocale 本地化信息的创建
NSLocale*localeOne = [[NSLocale alloc] initWithLocaleIdentifier:@"en_US"];——用标示符创建
NSLocale*localeTwo = [NSLocale systemLocale];——返回系统初始本地化信息
NSLocale*localeThree = [NSLocale currentLocale];——保持在 cache 中,用此方法实例化对象后,即使修改了本地化设定,也不会改变
NSLocale*localeFour = [NSLocale autoupdatingCurrentLocale];——每次修改本地化设定,其实例化的对象也会随之改变
2、NSLocale 本地化信息的设置
NSCalendar*calendar = [NSCalendar currentCalendar];
[calendar setLocale:[[NSLocale alloc] initWithLocaleIdentifier:@"en_US"]];
3、NSLocale 本地化信息的获取
NSString*strSymbol = [[NSLocale currentLocale] objectForKey:NSLocaleCurrencySymbol];
NSCalendar*calendar = [[NSLocalecurrentLocale] objectForKey:NSLocaleCalendar];
——根据不同的 key 返回各种本地化信息
4、显示特定地区代号下相应键的显示名称
NSLocale*locale = [[NSLocale alloc] initWithLocaleIdentifier:@"zh_CN"];
NSString*str = [locale displayNameForKey:NSLocaleIdentifiervalue:@"en_US"];
当NSDate *dateNow = [NSDate date]显示为:٢٠١٥٢٠١٥٢٠١٥的时候只需要在设置时间格式的时候加上上面设置就可以正确显示为:2015-09-18 07:10:45 如下图方法: