1、首先创建一个空白项目做测试
保证项目成功运行后,找到如下图的位置:
找到Localizations
,点击下面的+号,弹出所有可以选择的国际语言列表,按照项目需求选择就好,选完之后,上面的列表会自动添加对应选择的语言,如下图:
2、添加语言包
在任意路径下都可以,添加如下图的文件:
添加完成后,选中该文件,在Xcode工具最右侧的菜单栏中找到Localization
,把需要使用的语言包文件前面打勾即可,如下图:
这个时候,刚刚创建的.strings
文件变成了如下样式:
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、效果
全部代码按照上面的实现了之后,点手机屏幕看下效果,效果图如下:
中文:
英文: