iOS APP 内部切换语言
前言:相信大家都看过很多关于iOS国际化的文章,但是基本上都是跟随系统语言的国际化.笔者就不在这里赘述了.笔者今天要讲的是不跟随系统切换语言的方案,就像微信中切换语言那样,在应用内部就可以直接切换语言.
其实,应用内部切换语言的原理很简单,我总结为以下几个步骤:
1.配置国际化.
2.找到对应语言的配置文件(.strings),读取文件中的内容,修改语言.
3.重启app(重新设置window的rootViewController).
接下来,笔者就详细的说明一下是如何操作的.
一.新建工程,取名为ChangeLauguage.
项目很简单,只有一页,但是存在UINavigationController和UITabBarController.页面上存在两个button,一个是"切换到英文",另一个是"切换到中文".
AppDelegate.m文件
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
DDFirstViewController *firstVC = [[DDFirstViewController alloc] init];
firstVC.tabBarItem = [[UITabBarItem alloc] initWithTabBarSystemItem:UITabBarSystemItemHistory tag:10000];
UINavigationController *firstNC = [[UINavigationController alloc] initWithRootViewController:firstVC];
UITabBarController *tabBC = [[UITabBarController alloc] init];
[tabBC setViewControllers:@[firstNC]];
[self.window setRootViewController:tabBC];
[self.window makeKeyAndVisible];
return YES;
}
二.配置国际化,配置文件名称为ChangeLanguage.strings,配置语言为中文和英文.
注:如果不知道如何配置国际化,请参考http://www.jianshu.com/p/830a3397a20d
英文的配置文件中:
"homePage" = "homePage";
"changeToEnglish" = "changeToEnglish";
"changeToChinese" = "changeToChinese";
中文的配置文件中:
"homePage" = "首页";
"changeToEnglish" = "切换到英文";
"changeToChinese" = "切换到中文";
三.修改语言,重启app.
这部分是APP内部修改语言的关键部分,而这部分的重点就是: NSLocalizedStringFromTableInBundle(<#key#>, <#tbl#>, <#bundle#>, <#comment#>) 这个宏定义,从指定bundle的table中返回key对应的值.下面就详细介绍一下如何修改语言.
首先,我们需要一个语言管理类 DDLanguageTool 来管理语言的切换,因为需要全局修改语言,所以将其设计为单例.
#import <Foundation/Foundation.h>
#define ZH @"zh-Hans"
#define EN @"en"
/**
加载设定的语言
*/
#define DDGetStringWithKeyFormTable(key, table) [[DDLanguageTool shareInstance] getStringForKey:key fromTable:table]
@interface DDLanguageTool : NSObject
+ (id)shareInstance;
/**
设置新语言
@param language 新语言 中文:ZH 英文:EN
*/
- (void)setNewLanguage:(NSString *)language;
/**
从table中获得key对应的值
@param key 当前修改语言的key
@param table 当前修改语言的table
@return 返回table中key对应的值
*/
- (NSString *)getStringForKey:(NSString *)key fromTable:(NSString *)table;
@end
其中宏定义的 ZH 和 EN 分别表示中文和英文对应的bundle名称(注:如果不知道如何写这个名字,可以到工程的目录下,找到后缀是lproj的文件夹,文件夹的名字便是这个名字.其中Base.lproj是系统默认的)
对应的.m文件:
#import "DDLanguageTool.h"
#import "AppDelegate.h"
#import "DDFirstViewController.h"
#define DDLAUGUAGESET @"DDLAUGUAGESET"
@interface DDLanguageTool ()
//当前选择的bundle
@property (nonatomic, strong) NSBundle *currentBundle;
//当前选择的语言
@property (nonatomic, strong) NSString *currentLanguage;
@end
@implementation DDLanguageTool
+ (id)shareInstance
{
static DDLanguageTool *tool = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
tool = [[self alloc] init];
});
return tool;
}
- (instancetype)init
{
self = [super init];
if (self) {
[self initLanguage];
}
return self;
}
/**
初始化语言(修改后的语言)
修改语言完成后将修改后的语言保存在本地,下次启动app时,继续加载修改后的语言
*/
- (void)initLanguage
{
NSString *language = [[NSUserDefaults standardUserDefaults] objectForKey:DDLAUGUAGESET];
//如果获取的语言为空 就将语言设置为英语
if (language == nil || [language isEqualToString:@""]) {
language = EN;
}
self.currentLanguage = language;
NSString *bundlePath = [[NSBundle mainBundle] pathForResource:language ofType:@"lproj"];
self.currentBundle = [NSBundle bundleWithPath:bundlePath];
}
/**
@return 返回table中key对应的值
*/
- (NSString *)getStringForKey:(NSString *)key fromTable:(NSString *)table
{
return NSLocalizedStringFromTableInBundle(key, table, self.currentBundle, @"");
}
/**
设置新语言
*/
- (void)setNewLanguage:(NSString *)language
{
if (![language isEqualToString:EN] && ![language isEqualToString:ZH]) {
NSLog(@"设置了错误的语言");
return;
}
//如果设置的新语言与上次的语言相同,不做任何操作
if ([language isEqualToString:self.currentLanguage]) {
return;
}
self.currentLanguage = language;
NSString *bundlePath = [[NSBundle mainBundle] pathForResource:language ofType:@"lproj"];
self.currentBundle = [NSBundle bundleWithPath:bundlePath];
//保存当前设置的语言
[[NSUserDefaults standardUserDefaults] setObject:language forKey:DDLAUGUAGESET];
[[NSUserDefaults standardUserDefaults] synchronize];
//重启app
[self resetRootViewController];
}
/**
重启app(重新设置rootViewController)
*/
- (void)resetRootViewController
{
//设置rootViewController
AppDelegate *appDelegate = (AppDelegate *)[UIApplication sharedApplication].delegate;
DDFirstViewController *firstVC = [[DDFirstViewController alloc] init];
firstVC.title = DDGetStringWithKeyFormTable(@"homePage", @"ChangeLauguage");
firstVC.tabBarItem = [[UITabBarItem alloc] initWithTabBarSystemItem:UITabBarSystemItemHistory tag:10000];
UINavigationController *firstNC = [[UINavigationController alloc] initWithRootViewController:firstVC];
UITabBarController *tabBC = [[UITabBarController alloc] init];
[tabBC setViewControllers:@[firstNC]];
[appDelegate.window setRootViewController:tabBC];
}
@end
ViewController进行如下设置便可:
self.title = DDGetStringWithKeyFormTable(@"homePage", @"ChangeLauguage");
[eBtn setTitle:DDGetStringWithKeyFormTable(@"changeToEnglish", @"ChangeLauguage") forState:UIControlStateNormal];
[cBtn setTitle:DDGetStringWithKeyFormTable(@"changeToChinese", @"ChangeLauguage") forState:UIControlStateNormal];
至此,APP内部修改语言便完成了.如有疑问,欢迎留言.
项目地址:https://github.com/Poseidong/DDChangeLanguage-Demo
效果图:
1.gif