zoukankan      html  css  js  c++  java
  • iOS6和iOS7代码的适配(6) —— NSLocalizedString

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

    1. 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里面存储这当前的语言列表,我们可以获得这张列表,然后调整顺序,这样,我们可以确保默认语言放在第二个。代码如下:

    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. }  
        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文件

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

    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. }  
    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这样方便,所以我们再用宏包装一下:

    1. #define MYLocalizedString(key, comment)   
    2. [self get:(key) alter:(comment)]  
    #define MYLocalizedString(key, comment) 
    [self get:(key) alter:(comment)]

          使用的时候如下:

    1. [self setLanguage:[self getCurrentLanguage]];  
    2. 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

  • 相关阅读:
    CORS(跨域)请求总结和测试
    使用parted 创建一个大于2T的分区
    Linux下网络设置
    Linux中文件查找,压缩和打包指令
    使用switchshow/supportshow命令确认Brocade交换机型号(转载)
    光纤交换机端口故障排查
    博科5300光纤交换机内存故障处理
    AIX用户和组管理
    AIX 逻辑卷简介
    AIX中文件系统管理
  • 原文地址:https://www.cnblogs.com/geek6/p/3840644.html
Copyright © 2011-2022 走看看