iOS国际化

相关问题

国际化官网链接

  1. Infoplist.strings为什么可以替换info.plist的名称?什么时机替换的?为什么必须叫InfoPlist.strings?
  • 导出本地化时,Xcode包含一个InfoPlist.strings用于转换的文件。但是,此文件包含有关您的应用和公司的属性,因此您可能需要自己验证或翻译此文件。此字符串文件允许您可选地本地化信息属性列表中的某些属性值,例如应用程序名称(包显示名称)和版权声明。
  • Xcode会自动将这些键添加到InfoPlist.strings文件中:
    CFBundleDisplayName
    CFBundleName
    CFBundleShortVersionString
    NSHumanReadableCopyright

有关信息属性列表的完整说明,请参阅信息属性列表键参考

  1. 多target国际化添加说明
  • 工程包含多个target的时候需要创建对应target名字的文件(方便区分),然后在每个文件中分别生成InfoPlist.strings文件,再一一对应勾选相关target皆可以实现不同的target读取其唯一对应的InfoPlist.strings文件了,具体看展示图.
    生成多个文件多个.strings文件
按名字对应勾选target
  1. Localizable.strings == 匹配系统宏
  • 在运行时,NSLocalizedString 会确定首选的语言,并在应用程序包中找到相应的 Localizable.strings 文件。例如,如果用户首选法语,文件 fr.lproj/Localizable.strings 将来用作参考。
  • Localizable.strings 文件最初将由 genstrings 产生。genstrings 程序用给定的参数从 C 或 Objective-C(.c 或 .m)的源代码文件生成一个 .strings 文件。一个 .strings 文件用于为应用程序的不同语言作本地化,正如 Cocoa 开发者文档下的 “Internationalization” 描述的那样。
  1. 自定义文字国际化,方法参数说明
参数
key
指定表中字符串的键。
tableName
包含键值对的表的名称。此外,字符串文件的后缀(具有.strings扩展名的文件)用于存储本地化字符串。
comment
注释放在字符串文件中的键值对之上。
#define NSLocalizedStringFromTable(key, tbl, comment)
  • 从OS X 10.11和iOS 9开始,它NSBundle是线程安全的。因此,可以安全地从任何执行上下文中调用。
  1. 两种启动图国际化,各有各的问题,启动图缓存问题
    缓存图片需要删除APP再安装
    黑屏问题
  • iOS 8.0之前,系统优先选用 Launch Image 作为启动图.
  • iOS 8.0以后,系统优先选用 Launch Screen 作为启动图 (注意, Info.plist文件中,Launch screen interface file base name 需要填写对应的storyboard名称).
  • 如果你 LauncScreen 和 LaunchImage 同时都使用了,就有可能出现启动图黑屏 (建议只使用一种).
  • 使用 LaunchImage 时出现黑屏,需要检查以下几个地方: (在LaunchScreen 将Info.plist中的 Launch screen interface file base name 删除,可解决黑屏).
  1. Xib存在的问题:不能时时变换;&& 我们的工程不能用
  • xib的国际化,如果把xib放在framework或者bundle中,xib的国际化文件中不能切换对应语言环境的xib.strings文件。
  1. 不同系统适配问题

做指定语言切换开发与测试过程中最好使用真机代替模拟器,避免同语言在模拟器读取语言不准确。比如简体中文环境下,模拟器11.4版本iPhone8:“zh-Hans-US”,真机11.2.1版本iPhoneX:“zh-Hans-CN”。

由外到内的顺序进行国际化配置,文章最后会有demo与语言切换的简单工具类。

  • 1.APP名称国际化。
  • 2.系统权限提示语国际化。
  • 3.语言与图片国际化。
  • 4.启动图国际化。
  • 5.xib国际化。
  • 6.获取本地语言与语言切换。

1.APP名称国际化

InfoPlist.strings文件中,定义key和value.

  • 1.1 设置支持的语言,点“➕”添加,点击finish确定。

    APP名称-1.png

  • 1.2 生成InfoPlist.strings文件,名字必须写成InfoPlist里面才能支持名称国际化。

    国际化名称-2.png

  • 1.3 选中创建好的InfoPlist.strings文件,点击右侧Localize

    名称国际化-3.png

  • 1.4 添加文件点确定。
    这里涉及一点问题,添加文件时默认的是English语言环境,因为是在此项目中默认的环境是English所以少了Base文件的选项。修改方法---直接在info.plist文件添加此key就可以,把en改成zh-Hans就是默认语言为简体中文。在其他语言的情况下都使用此语言(非strings配置过的语言环境下).

<key>CFBundleDevelopmentRegion</key> 
<string>en</string>

关于CFBundleDevelopmentRegion
官网: CFBundleDevelopmentRegion (String - iOS, OS X) specifies the default language and region for the bundle, as a language ID. For example, English for the United Kingdom has the language ID en-UK. The system uses this value if it cannot locate a resource for the user’s preferred language.
翻译:CFBundleDevelopmentRegion(String - iOS,OS X)指定的默认语言和区域包,作为一种语言ID。例如,英国英语语言ID en-UK。系统使用这个值如果不能找到一个资源用户的首选语言。

关于Base文件
Base多语言默认文件,被其它多语言 (Chinese, English, ...) 继承和覆盖,不会被iOS直接使用,只有当对应的多语言文件中没有找到相应条目时才会到Base中查找,作用跟函数参数的默认值差不多。
查找原理App启动时,iOS会遍历用户设定的语言优先级去和App的多语言文件匹配如果匹配,会使用对应的语言如果不匹配,会使用plist中开发地区所对应的语言。

  • 1.5 勾选需要环境语言文件,把需要的语言选项勾选上。


    名称-5.png
  • 1.6 这时候右边文件列表会出现infoPlist.strings文件列表,选中指定语言环境的strings文件,配置国际化APP名称。

    名称-6.png

  • 1.7 设置名称需要在strings文件中对应设置"CFBundleDisplayName" = "xxxxx";,APP就会在对应的系统语言环境下显示不同strings里设置的名称了。

名称-7.png

2.系统权限提示语国际化

InfoPlist.strings文件中,定义key和value.
关于系统权限提示语的国际化,和设置APP名称一样需要在InfoPlist.strings文件里配置。

  • InfoPlist.strings文件里
  • 当然也可以在info.plist文件下配置默认提示语(没有配置过的其他语言环境下)

配置好系统在不同语言环境下的权限提示就会显示所对应的提示语。一批访问权限的对应字段。

NSBluetoothPeripheralUsageDescription   访问蓝牙
NSCalendarsUsageDescription   访问日历
NSCameraUsageDescription   相机
NSPhotoLibraryUsageDescription   相册
NSContactsUsageDescription   通讯录
NSLocationAlwaysUsageDescription   始终访问位置
NSLocationUsageDescription   位置
NSLocationWhenInUseUsageDescription   在使用期间访问位置
NSMicrophoneUsageDescription   麦克风
NSAppleMusicUsageDescription   访问媒体资料库
NSHealthShareUsageDescription   访问健康分享
NSHealthUpdateUsageDescription   访问健康更新
NSMotionUsageDescription   访问运动与健身
NSRemindersUsageDescription   访问提醒事项
  • 切换info.plistkey/value展示列表的方法
    info.plist-show

3.语言与图片国际化

简单情况(APP初期开发或个人开发是国际化处理)

  • 3.1 和建立APP名称国际化InfoPlist.strings文件一样,建立Localizable.strings文件,定义key和value.

    Localizable.strings

  • 3.2 分别在不同的Localizable.strings文件设置相应的key与value:

    设置相应key-value

  • 3.3 使用系统宏定义设置文字
    NSLocalizedString传递的第一个参数是当前国际化文字的key,第二个参数是注释comment,这个参数可有可为nil;当国际化文件某一语言中没有对应的指定国际化信息的时候,默认会以key的值来显示。

- (void)viewDidLoad {
    [super viewDidLoad];
    self.titleLabel.text = NSLocalizedString(@"title", nil);
}
  • 3.4 切换系统可以看到不同的文字展示


    香港繁体语言环境下

    简体中文语言环境下

简单的图片国际化与上述文字国际化是一样的,就是根据一样的图片key对应展示不同的图片value,就不上图片了 比如这样:

//  Localizable.strings文件中
"title" = "中文简体标题";
"imageKey" = "image_simplified";

//  Localizable.strings文件中
"title" = "香港繁體標題";
"imageKey" = "image_traditional";

// 控制器里设置控件
UIImage * iamge = [UIImage imageNamed:NSLocalizedString(@"imageKey", nil)];


多人开发/后期国际化
生成不同的.strings文件,使用系统的宏定义从不同文件中获取国际化文本

#define NSLocalizedStringFromTable(key, tbl, comment) \
        [NSBundle.mainBundle localizedStringForKey:(key) value:@"" table:(tbl)]
A-B两个不同strings文件

使用NSLocalizedStringFromTable定义国际化文本。

NSString *nameStr = NSLocalizedStringFromTable(@"name", @"XesA", nil);
    self.titleLabel.text = nameStr;

4.启动图国际化

(启动图国际化如果切换语言后无法达到显示结果,需要删除APP再次运行)

  • LaunchScreen启动图国际化

  • 4.1 配置好使用LaunchScreen作为启动图的配置文件

  • 4.2 创建不同语言环境下的LaunchScreen.storyboard启动页。

  • 4.3 分别画好不同LaunchScreen的启动效果,然后在InfoPlist.strings文件下配置不同语言环境下的指定LaunchScreen文件,如图

strings文件里的启动图配置

"UILaunchStoryboardName" = "LaunchS_Chine";
"UILaunchStoryboardName" = "LaunchS_HKHK";

5.xib国际化

xib国际化比较麻烦,因为生成xib对应的.strings文件后,再更改时不能动态修改对应的.strings文件,还需要重置此文件,笨方法就是先制作好了xib 最后再对应生成不同环境下的.strings文件,还有就是使用脚本动态生成国际化内容。(待研究学习...)

  • 5.1 创建带xib的控制器,设置其Label的布局与文字后,点击右侧Localizable添加多语言strings文本。(建议变动的xib文本可以把控件与控制器关联,在控制器中再进行国际化处理)

    xib-1.png

  • 5.2 和上面添加对应Localizable.strings文件一样,xib里的文本会自动生成下图这样:

    xib-4.png

  • 5.3 分别在xib下不同的.strings文件设置对应文本,切换系统后就会变更,显示国际化对应文本。

也可以把xib里的控件与其控制器关联,在控制器中再进行国际化文本处理。


6.获取本地语言与语言切换

在做获取本地语言与语言切换功能时,最好使用真机测试比较准确,比如同样系统下的模拟器与真机获取简体中文就会有偏差,模拟器的简体中文为zh-Hans-US,真机为zh-Hans-CN,虽然都可以表示简体中文 但会有偏差。

// 获取当前语言环境
// 方法一
 NSArray *languageArry = [NSLocale preferredLanguages];
 NSString *currentLanguage = [languageArry objectAtIndex:0];

// 方法二
 NSArray * languageArry = [[NSUserDefaults standardUserDefaults]  objectForKey:@"AppleLanguages"];
 NSString * currentLanguage = [allLanguages objectAtIndex:0];

// 获取当前设备支持语言数组
NSArray *languageArr = [NSLocale availableLocaleIdentifiers];

更改当前APP所属语言环境(语言切换)只需要在NSUserDefaults下的keyAppleLanguages赋相应的语言代码就好。
比如把当前app语言环境改成英文。

[[NSUserDefaults standardUserDefaults] setObject:@"en-US" forKey:@"AppleLanguages"];
[[NSUserDefaults standardUserDefaults] synchronize];
切换语言时的常见思路
  • 1.发送通知NSNotification(类似微博),切换语言的时候发送通知刷新所有涉及的页面,当然每个页面的每个控件都需要有自己的一套更新机制,比较繁琐。

  • 2.刷新重置keyWindow的rootViewController(类似微信)最简单实用。当然也需要根据需求定一个适合的方案。


国际化语言适配问题笔记
iOS8  
简体中文:zh-Hans
繁体中文香港:zh-HK

iOS9    
简体中文: zh-Hans-CN
香港繁体  : zh-HK

iOS10及以上
简体中文   zh-Hans-CN
香港繁体: zh-Hant-HK

官网国际化指南

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,324评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,303评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,192评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,555评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,569评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,566评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,927评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,583评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,827评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,590评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,669评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,365评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,941评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,928评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,159评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,880评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,399评论 2 342

推荐阅读更多精彩内容

  • 之前公司的app可能要在岛国和东南亚地区使用,所以最合理的方法就是--国际化。 写这篇文章也是为一个妹子写的(咦~...
    伦敦乡下的小作家阅读 792评论 4 4
  • iOS国际化简单操作 国际化后的App可以根据手机当前系统语言来切换不同的语言来适应不同的语言使用人群, 所以iO...
    zhouyuhan阅读 856评论 2 7
  • 国际化(Internationalization ,简写为I18N)的作用是防止将本土文化信息写死仔应用里(所谓本...
    西西西瓜啊阅读 11,240评论 23 15
  • Demo同步更新到Swift2.3本文地址: http://mokai.me/iOS-i18n.html 在真正...
    _GKK_阅读 5,777评论 13 55
  • 四月的北国天气变化无常。早上还是阳光普照,到了中午就变成了大雪纷飞。那些雪花哟,彷佛是从阳光的间隙中飘下来的精灵,...
    徐健舒阅读 576评论 0 0