iOS6和iOS7代码的适配(6) —— NSLocalizedString
我们的应用都是需要国际化的,字符串也是重要的一环。一般来说,我们是通过一个string资源文件来实现这个目的的,我们需要支持几种语言,就把这个文件本地化多少次。代码中需要用NSLocalizedString这个宏,比如,我希望设置一个tableView的title:
- self.navigationItem.title = NSLocalizedString(@"test", nil);
self.navigationItem.title = NSLocalizedString(@"test", nil);
我们这里加了英文和简体中文两种语言。
如果客户选择了我们没有本地化的语言呢?比如,我们选择了繁体中文,那么这个title会显示什么呢?我们一般都希望显示英语。这点在iOS7以前确实没问题,但在iOS7上就变了,你会发现这个语言会选择前一次使用的语言。也就是说,在iOS7上,我先选择,英语,然后换成简体中文,最后换成繁体中文,此时会显示简体中文!
我在开发的一个应用也遇到了这个问题,经过检查,发现这是iOS7调整了语言的顺序导致的。
对比setting页的多国语言设定页:
我们可以很清楚的看出,iOS6上,英语总是位于第二,余下的按照你的设置顺序反向排列;而iOS7不是这样的,它完全是按照你设置语言的顺序反向排列。
在我们调用NSLocalizedString这个宏的时候,系统会按照这个顺序去找本地化的语言文件。这样,当我们选择了繁体中文时,系统发现没有这个语言的本地化,于是按照顺序去逐个检测,iOS6就会使用英语,而iOS7就会使用上一次的语言。
原因已经确定了,那么我们怎么修改呢?有两种方法,下面我们一一来讲。
1. 把应用需要的默认语言放到语言表的第二个位置上,这样可以确保当前语言没有本地化时会显示默认语言
我们知道在UserDefault里面的AppleLanguages里面存储这当前的语言列表,我们可以获得这张列表,然后调整顺序,这样,我们可以确保默认语言放在第二个。代码如下:
- NSMutableArray *langArray = [[NSUserDefaults standardUserDefaults] arrayForKey:@"AppleLanguages"];
- NSUInteger def_lang_index = [langArray indexOfObject:@"en"];
- if (def_lang_index != 1 && def_lang_index != 0) {
- NSMutableArray *tempArray = [NSMutableArray arrayWithObjects:langArray[0], @"en", nil nil];
- [langArray removeObject:langArray[0]];
- [langArray removeObject:@"en"];
- [tempArray addObjectsFromArray:langArray];
- [[NSUserDefaults standardUserDefaults] setObject:tempArray forKey:@"AppleLanguages"];
- [[NSUserDefaults standardUserDefaults]synchronize];
- }
NSMutableArray *langArray = [[NSUserDefaults standardUserDefaults] arrayForKey:@"AppleLanguages"];
NSUInteger def_lang_index = [langArray indexOfObject:@"en"];
if (def_lang_index != 1 && def_lang_index != 0) {
NSMutableArray *tempArray = [NSMutableArray arrayWithObjects:langArray[0], @"en", nil];
[langArray removeObject:langArray[0]];
[langArray removeObject:@"en"];
[tempArray addObjectsFromArray:langArray]; [[NSUserDefaults standardUserDefaults] setObject:tempArray forKey:@"AppleLanguages"];
[[NSUserDefaults standardUserDefaults]synchronize];
}
需要注意的是,这份代码必须放在main.m文件里面UIApplicationMain()之前,否则,应用本次是不起作用的,只能在下次起作用。
2. 指定Bundle里面的resource文件
第一种方法虽然一劳永逸,但感觉修改的很粗暴,不够优雅!第二种方法才能突出我们程序员们的高大上,不多说了,上代码!
- static NSBundle *bundle = nil;
- - (NSString*)getCurrentLanguage
- {
- NSArray *langArray = [[NSUserDefaults standardUserDefaults] arrayForKey:@"AppleLanguages"];
- return langArray[0];
- }
- - (void)setLanguage:(NSString *)l {
- NSLog(@"preferredLang: %@", l);
- NSString *path = [[ NSBundle mainBundle ] pathForResource:l ofType:@"lproj" ];
- if (!path) {
- path = [[ NSBundle mainBundle ] pathForResource:@"en" ofType:@"lproj" ];
- //[self resetLocalization];
- }
- bundle = [NSBundle bundleWithPath:path];
- }
- - (NSString *)get:(NSString *)key alter:(NSString *)alternate {
- return [bundle localizedStringForKey:key value:alternate table:nil];
- }
static NSBundle *bundle = nil; - (NSString*)getCurrentLanguage
{
NSArray *langArray = [[NSUserDefaults standardUserDefaults] arrayForKey:@"AppleLanguages"];
return langArray[0];
} - (void)setLanguage:(NSString *)l {
NSLog(@"preferredLang: %@", l);
NSString *path = [[ NSBundle mainBundle ] pathForResource:l ofType:@"lproj" ];
if (!path) {
path = [[ NSBundle mainBundle ] pathForResource:@"en" ofType:@"lproj" ];
//[self resetLocalization];
}
bundle = [NSBundle bundleWithPath:path]; } - (NSString *)get:(NSString *)key alter:(NSString *)alternate {
return [bundle localizedStringForKey:key value:alternate table:nil];
}
这几个方法分别是获得当前语言,设置语言——如果没有资源文件就是用默认语言,最后的get:alter:方法就是实际调用的方法,当然,这个没有NSLocalizedString这样方便,所以我们再用宏包装一下:
- #define MYLocalizedString(key, comment) \
- [self get:(key) alter:(comment)]
#define MYLocalizedString(key, comment) \
[self get:(key) alter:(comment)]
使用的时候如下:
- [self setLanguage:[self getCurrentLanguage]];
- self.navigationItem.title = MYLocalizedString(@"test", nil);
[self setLanguage:[self getCurrentLanguage]];
self.navigationItem.title = MYLocalizedString(@"test", nil);
OK,结束了,赶紧试一下吧。
这两种方法都可以使用,个人当然推荐第二种方法,如果第二种方法在扩充一下,可以自己写一个类,这样我们可以确保所有的项目的使用了。
http://blog.csdn.net/sakulafly/article/details/25489863
iOS6和iOS7代码的适配(6) —— NSLocalizedString的更多相关文章
- iOS6和iOS7代码的适配(1)
苹果的iOS7推出后,对于所有的应用来说都提出了一个天然的需求--适配不同版本的SDK.目前来说,用iOS6的SDK生成的应用,可以在iOS7的系统上跑,UI上也保持了原来的风格样式,这是苹果做的向下 ...
- iOS6和iOS7代码的适配(3)——坐标适配
由于iOS7里面status bar和视图是重叠在一起了,所以应用的y坐标就没法和以前一致了,需要重新计算设定.基本上,你的应用用Xcode5运行一下就能看见这个问题,这里写了一个最简单的例子,一个V ...
- iOS6和iOS7代码的适配(5)——popOver
popOver这个空间本身是iPad only的,所以iPhone上见不到,我记得微信上有个这样的弹出框,有扫一扫等几个菜单项,估计这是腾讯自己实现的,用于菜单的扩展. popOver从iOS6到iO ...
- iOS6和iOS7代码的适配(4)——tableView
iOS7上不少控件的样子有了变化(毕竟要扁平化嘛),不过感觉变化最大的肯定非tableView莫属.因为这个控件的高度可定制性,原先是使用及其广泛的,这样的一个改变自然也影响颇大. 1.accesso ...
- iOS6和iOS7代码的适配(2)——status bar
用Xcode5运行一下应用,第一个看到的就是status bar的变化.在iOS6中,status bar是系统在处理,应用中不需要考虑这部分,iOS7之后是应用在处理,每个ViewControlle ...
- IOS6和IOS7的屏幕适配问题
自从IOS7出来以后,以前写在IOS6上或者更低版本的程序,跑在IOS7的模拟器上就会出现一些问题.最大的问题就是,所有的UI空间都会统一向上移动20个点(如果空间的y值为0,就会被StatusBar ...
- (ios7) 解决代码布局View, ios7 中 subView 高度增加StatusBar20dp的问题,保证Ios6,ios7代码一致
在ios7 布局中,Status Bar 和 ToolBar ,NavigateBar 等都包含在ViewControl的主View中. 这样原来ios6 的View布局 整体向上移动了20dp,下面 ...
- 适配iOS6与iOS7
适配屏幕其实很简单,但为了保持兼容性以及写的代码的通用性,以及最小的改动代码,本人按照如下的一种方式来适配,可以一劳永逸. 1. 先定义几个宏,分辨表示应用可以使用区域的高度,屏幕可用区域的高度,屏幕 ...
- iOS- <项目笔记>iOS6 & iOS7屏幕图片适配
1.为非视网膜\视网膜屏幕分别准备2份图片,比如: 1> 非视网膜 abc.png 2> 视网膜 abc@2x.png 程序检测视网膜屏到会自动替换@2x 2.程序启动图片 * 程序启动过 ...
随机推荐
- Oracle数据库PLSQL的中文乱码显示全是问号
plsql连接数据库乱码问题 缘由: 小师妹周末叫我帮她重装数据库,这么大好的周末时光不出去玩儿,给她装数据库这不是很蛋疼么. 我问她为什么要重装,她说:数据存入数据库后,中文字符有乱码,一定是我上次 ...
- NOIP 能量项链
描述 在Mars星球上,每个Mars人都随身佩带着一串能量项链.在项链上有N颗能量珠.能量珠是一颗有头标记与尾标记的珠子,这些标记对应着某个正整数.并且,对于相邻的两颗珠子,前一颗珠子的尾标记一定等于 ...
- 解析JDK动态代理实现原理
JDK动态代理使用实例 代理模式的类图如上.关于静态代理的示例网上有很多,在这里就不讲了. 因为本篇讲述要点是JDK动态代理的实现原理,直接从JDK动态代理实例开始. 首先是Subject接口类. p ...
- cf780c
C. Andryush ...
- 转: 在hibernate中查询使用list,map定制返回类型
在使用hibernate进行查询时,使用得最多的还是通过构建hql进行查询了.在查询的过程当中,除使用经常的查询对象方法之外,还会遇到查询一个属性,或一组聚集结果的情况.在这种情况下,我们通常就需要对 ...
- 2017 湘潭邀请赛&JSCPC G&J
训练的时候对G想了一个假算法..也有很大可能是写错了.. 下来一看别人的G 看起来很奇妙.. 开始把所有的左括号翻成右括号,然后cost*=-1 这样在优先队列中就是最优的 然后for每一段 如果前缀 ...
- Ubuntu 16 安装redis客户端
https://snapcraft.io/redis-desktop-manager sudo snap install redis-desktop-manager 很好用! 支持模糊过滤,两边加星号 ...
- svn官方版本的使用
创建仓库的命令是:svndadmin create c:\abcde 启动命令是:svnserve -d -r c:\abcde 官方版本,svn路径
- extundelete实现Linux下文件/文件夹数据恢复!
我用的是Centos系统,在安装extundelete之前需要安装e2fsprogs,e2fsprogs-libs,e2fsprogs-devel. 这里用:yum install e2fsprogs ...
- Tkinter Button按钮组件如何调用一个可以传入参数的函数
这里我们要使用python的lambda函数,lambda是创建一个匿名函数,冒号前十传入参数,后面是一个处理传入参数的单行表达式. 调用lambda函数返回表达式的结果. 首先让我们创建一个函数fu ...