相关问题
- Infoplist.strings为什么可以替换info.plist的名称?什么时机替换的?为什么必须叫InfoPlist.strings?
- 导出本地化时,Xcode包含一个InfoPlist.strings用于转换的文件。但是,此文件包含有关您的应用和公司的属性,因此您可能需要自己验证或翻译此文件。此字符串文件允许您可选地本地化信息属性列表中的某些属性值,例如应用程序名称(包显示名称)和版权声明。
- Xcode会自动将这些键添加到
InfoPlist.strings
文件中:
CFBundleDisplayName
CFBundleName
CFBundleShortVersionString
NSHumanReadableCopyright
有关信息属性列表的完整说明,请参阅信息属性列表键参考。
- 多target国际化添加说明
- 工程包含多个target的时候需要创建对应target名字的文件(方便区分),然后在每个文件中分别生成
InfoPlist.strings
文件,再一一对应勾选相关target
皆可以实现不同的target
读取其唯一对应的InfoPlist.strings
文件了,具体看展示图.
- Localizable.strings == 匹配系统宏
- 在运行时,NSLocalizedString 会确定首选的语言,并在应用程序包中找到相应的 Localizable.strings 文件。例如,如果用户首选法语,文件 fr.lproj/Localizable.strings 将来用作参考。
- Localizable.strings 文件最初将由 genstrings 产生。genstrings 程序用给定的参数从 C 或 Objective-C(.c 或 .m)的源代码文件生成一个 .strings 文件。一个 .strings 文件用于为应用程序的不同语言作本地化,正如 Cocoa 开发者文档下的 “Internationalization” 描述的那样。
- 自定义文字国际化,方法参数说明
参数
key
指定表中字符串的键。
tableName
包含键值对的表的名称。此外,字符串文件的后缀(具有.strings扩展名的文件)用于存储本地化字符串。
comment
注释放在字符串文件中的键值对之上。
#define NSLocalizedStringFromTable(key, tbl, comment)
- 从OS X 10.11和iOS 9开始,它
NSBundle
是线程安全的。因此,可以安全地从任何执行上下文中调用。
-
两种启动图国际化,各有各的问题,启动图缓存问题
缓存图片需要删除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 删除,可解决黑屏).
- Xib存在的问题:不能时时变换;&& 我们的工程不能用
- xib的国际化,如果把xib放在
framework
或者bundle
中,xib的国际化文件中不能切换对应语言环境的xib
与.strings
文件。
- 不同系统适配问题
做指定语言切换开发与测试过程中最好使用真机代替模拟器,避免同语言在模拟器读取语言不准确。比如简体中文环境下,模拟器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
确定。
-
1.2 生成
InfoPlist.strings
文件,名字必须写成InfoPlist
里面才能支持名称国际化。
-
1.3 选中创建好的
InfoPlist.strings
文件,点击右侧Localize
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 勾选需要环境语言文件,把需要的语言选项勾选上。
-
1.6 这时候右边文件列表会出现
infoPlist.strings文件列表
,选中指定语言环境的strings
文件,配置国际化APP名称。
-
1.7 设置名称需要在
strings
文件中对应设置"CFBundleDisplayName" = "xxxxx";
,APP就会在对应的系统语言环境下显示不同strings
里设置的名称了。
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.plist
key/value展示列表的方法
3.语言与图片国际化
简单情况(APP初期开发或个人开发是国际化处理)
-
3.1 和建立APP名称国际化
InfoPlist.strings
文件一样,建立Localizable.strings
文件,定义key和value.
-
3.2 分别在不同的
Localizable.strings
文件设置相应的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)]
使用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文本可以把控件与控制器关联,在控制器中再进行国际化处理)
-
5.2 和上面添加对应
Localizable.strings
文件一样,xib里的文本会自动生成下图这样: 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