iOS 国际化语言包

1、首先创建一个空白项目做测试

保证项目成功运行后,找到如下图的位置:

WechatIMG558.png

找到Localizations,点击下面的+号,弹出所有可以选择的国际语言列表,按照项目需求选择就好,选完之后,上面的列表会自动添加对应选择的语言,如下图:

WechatIMG559.png

2、添加语言包

在任意路径下都可以,添加如下图的文件:

WechatIMG560.png

添加完成后,选中该文件,在Xcode工具最右侧的菜单栏中找到Localization,把需要使用的语言包文件前面打勾即可,如下图:

WechatIMG561.png

这个时候,刚刚创建的.strings文件变成了如下样式:

WechatIMG562.png

3、添加对应的语言

在每个语言包中,以键值对的方式添加对应的语言环境配置,类似:

英文的:"Home" = "Home";
中文的:"Home" = "首页";

前面的key不一定是英文,中文的或者其他的都可以,只要自己能看得懂。

4、添加语言切换辅助工具(重点!)

创建一个继承自NSObject的类,把下面的代码分别复制粘贴进.h和.m文件中,项目报错先不用管,下面还有需要做的事儿。

  • .h
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>

#define LYLManager [LYLanguageManager shareInstance]
#define LYLS(key) [LYLManager localizedStringForKey:key value:key]

#define UserLanguage @"userLanguage"

@interface LYLanguageManager : NSObject

+(instancetype)shareInstance;

//设置当前语言
-(void)setUserlanguage:(NSString *)language;

//获取对应语言包中的返回值
-(NSString *)localizedStringForKey:(NSString *)key value:(NSString *)value;

@end
  • .m
#import "LYLanguageManager.h"
#import "AppDelegate.h"

@interface LYLanguageManager ()

@property (nonatomic, strong) NSBundle *bundle;

@end

@implementation LYLanguageManager

+(instancetype)shareInstance{
    static LYLanguageManager *manager = nil;
    static dispatch_once_t oncePredicate;
    dispatch_once(&oncePredicate, ^{
        manager = [[self alloc] init];
    });
    return manager;
}

#pragma mark - 设置语言
-(void)setUserlanguage:(NSString *)language{
    
    if (![[self cacheLanguage] isEqualToString:language]){
        //保存当前语言
        [self saveLanguage:language];
        //修改语言包加载文件
        [self changeBundle:language];
        //重启程序
        [AppDelegate.app initRootView];
    }
    
}

#pragma mark - 保存语言
-(void)saveLanguage:(NSString *)language{
    /*
     按照需求缓存
     */
    [[NSUserDefaults standardUserDefaults] setObject:language forKey:@"lang"];
    [[NSUserDefaults standardUserDefaults] synchronize];
}

#pragma mark - 改变Bundle,初始化时也要给Bundle赋值
-(void)changeBundle:(NSString *)language{
    //1.第一步改变bundle的值
    NSString *path = [[NSBundle mainBundle] pathForResource:[self languageFormat:language]
                                                     ofType:@"lproj"];
    _bundle = [NSBundle bundleWithPath:path];
}

//语言和语言对应的.lproj的文件夹前缀不一致时在这里做处理
-(NSString *)languageFormat:(NSString*)language{
    
    //简体中文和繁体中文的.lproj文件前缀特殊,所以要单独处理
    if ([language containsString:@"zh-Hans"]) {
        language = @"zh-Hans";
    }else{
        if ([language containsString:@"-"]) {
            NSArray *array = [language componentsSeparatedByString:@"-"];
            if (array.count > 1) {
                language = array.firstObject;
            }
        }
    }
    return language;
    
}

#pragma mark - 获取当前语言,没有记录的情况下,默认返回英文
-(NSString *)cacheLanguage {
    NSString *lang = [[NSUserDefaults standardUserDefaults] objectForKey:@"lang"];
    return lang?:@"en-CN";
}

-(NSString *)localizedStringForKey:(NSString *)key value:(NSString *)value{
    
    if (key.length > 0) {
        
        if (!_bundle) {
            //初始化默认语言
            [self changeBundle:[self cacheLanguage]];
        }

        //第二个参数是语言包文件Language.strings的前缀
        NSString *result = NSLocalizedStringFromTableInBundle(key,
                                                              @"Language",
                                                              _bundle,
                                                              value);
        if (result.length > 0) {
            return result;
        }
        
    }
    return @"添加语言包";
    
}

@end

5、开始实现语言切换

  • 1、开始之前,需要先在AppDelegate中实现两个方法(这里只是思路,有更好的办法欢迎推荐),分别如下:
+(AppDelegate *)app;

-(void)initRootView;

至于为什么需要这两个方法,先看下整个AppDelegate.m文件的内容,这样比较直观,一眼就能看懂具体作用,如下:

#import "AppDelegate.h"
#import "ViewController.h"
#import "LYLanguageManager.h"

@interface AppDelegate ()

@end

@implementation AppDelegate

+(AppDelegate*)app{
    return (AppDelegate *)[[UIApplication sharedApplication] delegate];
}

-(void)initRootView{
    ViewController *view = [[ViewController alloc]init];
    view.title = LYLS(@"Home");
    UINavigationController *nav_view = [[UINavigationController alloc]initWithRootViewController:view];
    self.window.rootViewController = nav_view;
}

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // Override point for customization after application launch.
    
    self.window = [[UIWindow alloc]initWithFrame:[UIScreen mainScreen].bounds];
    self.window.backgroundColor = UIColor.whiteColor;
    [self.window makeKeyAndVisible];
    
    [self initRootView];
    
    return YES;
}


@end

这里有两个地方需要说明

第一:+(AppDelegate *)app;-(void)initRootView;两个方法实现的目的是为了切换语言的时候,让程序重新启动,通过第四步的辅助工具实现语言切换,在第四步.m文件中的-(void)setUserlanguage:(NSString *)language方法中可以看到[AppDelegate.app initRootView];

第二:LYLS(@"Home")这个写法,每一个需要显示语言包中的内容的地方,都必须这样写,否则无法正确显示各个语言包中的内容

  • 2、切换语言

这里我为了方便,直接利用一个BOOL值做管控,写在touchesBegan方法中,代码如下:

-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
    
    _isBol = !_isBol;
    [LYLManager setUserlanguage:_isBol?@"zh-Hans-CN":@"en-CN"];
    
}

这里需要注意的是-(void)setUserlanguage:(NSString *)language;这个方法了,每次传进去的值一定不要写错,不然就GG。

6、效果

全部代码按照上面的实现了之后,点手机屏幕看下效果,效果图如下:

中文:


WechatIMG563.png

英文:


WechatIMG564.png

7、全剧终

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。