在iOS中如何设置默认语言

在iOS的开发中,我们需要做本地化的动作,对一些资源(主要是字符串),在不同的语言下显示各自的内容。比如edit,在英语下显示“Edit”,中文下就是“编辑”。


最近做的项目客户要求支持两种语言,英语和意大利语,并且强调默认意大利语,要求当前语言非英语和意大利语是,显示意大利语。

本来以为xcode里面的Localization native development region这个选项就是设置默认的区域,这样在本地化的区域中显示本地化的资源,没有本地化的区域就显示默认的资源。但验证下来这项设置不是这个意思,默认的字符串采用的是英语,无论这个development region设置成什么,非本地化的区域显示的是英文。


为了实现这个默认语言的功能,只能尝试其他的途径,最后我用代码实现了,基本思路就是发现当前语言并非系统支持的英语和意大利语时,统一访问指定的资源文件,返回默认的资源,代码如下:

#define CURR_LANG                        ([[NSLocale preferredLanguages] objectAtIndex:0])

+ (NSString *)DPLocalizedString:(NSString *)translation_key {

    NSString * s = NSLocalizedString(translation_key, nil);

    if (![CURR_LANG isEqual:@"en"] && ![CURR_LANG isEqual:@"it"]) {

        NSString * path = [[NSBundle mainBundlepathForResource:@"it" ofType:@"lproj"];

        NSBundle * languageBundle = [NSBundle bundleWithPath:path];

        s = [languageBundle localizedStringForKey:translation_key value:@"" table:nil];

    }

    return s;

}


这样,代码中把使用的国际化的宏NSLocalizedString统一更改成DPLocalizdString就可以实现默认语言的修改了


 

iOS6和iOS7代码的适配(6) —— NSLocalizedString


     我们的应用都是需要国际化的,字符串也是重要的一环。一般来说,我们是通过一个string资源文件来实现这个目的的,我们需要支持几种语言,就把这个文件本地化多少次。代码中需要用NSLocalizedString这个宏,比如,我希望设置一个tableView的title:

[objc]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. self.navigationItem.title = NSLocalizedString(@"test", nil);  
      我们这里加了英文和简体中文两种语言。

      

      如果客户选择了我们没有本地化的语言呢?比如,我们选择了繁体中文,那么这个title会显示什么呢?我们一般都希望显示英语。这点在iOS7以前确实没问题,但在iOS7上就变了,你会发现这个语言会选择前一次使用的语言。也就是说,在iOS7上,我先选择,英语,然后换成简体中文,最后换成繁体中文,此时会显示简体中文!


      我在开发的一个应用也遇到了这个问题,经过检查,发现这是iOS7调整了语言的顺序导致的。

      对比setting页的多国语言设定页:

      

      我们可以很清楚的看出,iOS6上,英语总是位于第二,余下的按照你的设置顺序反向排列;而iOS7不是这样的,它完全是按照你设置语言的顺序反向排列。

      在我们调用NSLocalizedString这个宏的时候,系统会按照这个顺序去找本地化的语言文件。这样,当我们选择了繁体中文时,系统发现没有这个语言的本地化,于是按照顺序去逐个检测,iOS6就会使用英语,而iOS7就会使用上一次的语言。


      原因已经确定了,那么我们怎么修改呢?有两种方法,下面我们一一来讲。

1. 把应用需要的默认语言放到语言表的第二个位置上,这样可以确保当前语言没有本地化时会显示默认语言

      我们知道在UserDefault里面的AppleLanguages里面存储这当前的语言列表,我们可以获得这张列表,然后调整顺序,这样,我们可以确保默认语言放在第二个。代码如下:

[objc]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. NSMutableArray *langArray = [[NSUserDefaults standardUserDefaults] arrayForKey:@"AppleLanguages"];  
  2. NSUInteger def_lang_index = [langArray indexOfObject:@"en"];  
  3. if (def_lang_index != 1 && def_lang_index != 0) {  
  4.     NSMutableArray *tempArray = [NSMutableArray arrayWithObjects:langArray[0], @"en", nil nil];  
  5.     [langArray removeObject:langArray[0]];  
  6.     [langArray removeObject:@"en"];  
  7.     [tempArray addObjectsFromArray:langArray];  
  8.       
  9.     [[NSUserDefaults standardUserDefaults] setObject:tempArray forKey:@"AppleLanguages"];  
  10.     [[NSUserDefaults standardUserDefaults]synchronize];  
  11. }  
      需要注意的是,这份代码必须放在main.m文件里面UIApplicationMain()之前,否则,应用本次是不起作用的,只能在下次起作用。


2.  指定Bundle里面的resource文件

      第一种方法虽然一劳永逸,但感觉修改的很粗暴,不够优雅!第二种方法才能突出我们程序员们的高大上,不多说了,上代码!

[objc]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. static NSBundle *bundle = nil;  
  2.   
  3. - (NSString*)getCurrentLanguage  
  4. {  
  5.     NSArray *langArray = [[NSUserDefaults standardUserDefaults] arrayForKey:@"AppleLanguages"];  
  6.     return langArray[0];  
  7. }  
  8.   
  9. - (void)setLanguage:(NSString *)l {  
  10.     NSLog(@"preferredLang: %@", l);  
  11.     NSString *path = [[ NSBundle mainBundle ] pathForResource:l ofType:@"lproj" ];  
  12.     if (!path) {  
  13.         path = [[ NSBundle mainBundle ] pathForResource:@"en" ofType:@"lproj" ];  
  14.         //[self resetLocalization];  
  15.     }  
  16.     bundle = [NSBundle bundleWithPath:path];  
  17.       
  18. }  
  19.   
  20. - (NSString *)get:(NSString *)key alter:(NSString *)alternate {  
  21.     return [bundle localizedStringForKey:key value:alternate table:nil];  
  22. }  
      这几个方法分别是获得当前语言,设置语言——如果没有资源文件就是用默认语言,最后的get:alter:方法就是实际调用的方法,当然,这个没有NSLocalizedString这样方便,所以我们再用宏包装一下:

[objc]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. #define MYLocalizedString(key, comment) \  
  2. [self get:(key) alter:(comment)]  
      使用的时候如下:

[objc]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. [self setLanguage:[self getCurrentLanguage]];  
  2. self.navigationItem.title = MYLocalizedString(@"test", nil);  
      OK,结束了,赶紧试一下吧。


      这两种方法都可以使用,个人当然推荐第二种方法,如果第二种方法在扩充一下,可以自己写一个类,这样我们可以确保所有的项目的使用了。




  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值