想要实现App内的语言切换功能,那么首先要创建国际化语言文件,用于存储对应语言显示的文本。
1、创建国际化语言文件
command+N,选择Other里面的Empty文件。
我们将其命名为Localizable.strings
选中刚才创建的文件,在其右侧的的属性栏中点击Localize按钮。
2、设置项目需要支持的语言
选中project--->info--->Localization。
我们会发现里面默认有一个英语,我们可以点击左下角的➕号添加支持的语言。
点击+号,选择简体中文。
默认全选,点击完成即可:
这时我们展开Localizable.strings、Main.storyboard和LaunchScreen.storyboard,会看到多了一些文件。
3、文本国际化
大家看这个可能会有疑问,不知道是什么意思。
"首页" = "首页";
"首页" = "Homepage";
其实这两个是一个文本的不同语言的展示。“=”号左面的相当于key值;“=”号右面的相当于value值。不过为了使用方便,更容易理解,我这里直接使用了中文的内容作为key值。
使用方法的话:NSLocalizedString(@"首页", nil);
这样,在中文语言的时候返回“首页”(中文),在英文语言中返回“ Homepage”(英文)。
如果你是用xib或者Storyboard展示文本的话,想要文本国际化展示的话,需要另外的方法。
首先选中xib或者Storyboard,选中需要支持的语言。
我们可以看到对应的文件里面有对应的显示文本。如果要想xib随着设置的不同语言展示不同的文本的话,可以在这两个文件中修改。
4、本地存储语言设置
使用NSUserDefaults存储本地语言设置。
直接上代码:这是一位大神分享的代码,我复制了一份,效果很不错,看原文请点这里原文.
存储、获取、重置本地语言设置
#import <Foundation/Foundation.h>
@interface UWConfig : NSObject
/**
用户自定义使用的语言,当传nil时,等同于resetSystemLanguage
*/
@property (class, nonatomic, strong, nullable) NSString *userLanguage;
/**
重置系统语言
*/
+ (void)resetSystemLanguage;
@end
#import "UWConfig.h"
static NSString *const UWUserLanguageKey = @"UWUserLanguageKey";
#define STANDARD_USER_DEFAULT [NSUserDefaults standardUserDefaults]
@implementation UWConfig
+ (void)setUserLanguage:(NSString *)userLanguage
{
//跟随手机系统
if (!userLanguage.length) {
[self resetSystemLanguage];
return;
}
//用户自定义
[STANDARD_USER_DEFAULT setValue:userLanguage forKey:UWUserLanguageKey];
[STANDARD_USER_DEFAULT setValue:@[userLanguage] forKey:@"AppleLanguages"];
[STANDARD_USER_DEFAULT synchronize];
}
+ (NSString *)userLanguage
{
return [STANDARD_USER_DEFAULT valueForKey:UWUserLanguageKey];
}
/**
重置系统语言
*/
+ (void)resetSystemLanguage
{
[STANDARD_USER_DEFAULT removeObjectForKey:UWUserLanguageKey];
[STANDARD_USER_DEFAULT setValue:nil forKey:@"AppleLanguages"];
[STANDARD_USER_DEFAULT synchronize];
}
@end
切换bundle
#import <Foundation/Foundation.h>
@interface NSBundle (UWUtils)
+ (BOOL)isChineseLanguage;
+ (NSString *)currentLanguage;
@end
#import "NSBundle+UWUtils.h"
#import "UWConfig.h"
#import <objc/runtime.h>
@interface UWBundle : NSBundle
@end
@implementation NSBundle (UWUtils)
+ (BOOL)isChineseLanguage
{
NSString *currentLanguage = [self currentLanguage];
if ([currentLanguage hasPrefix:@"zh-Hans"]) {
return YES;
} else {
return NO;
}
}
/*
* 设置默认语言类型
*/
+ (NSString *)currentLanguage
{
// return [UWConfig userLanguage] ? : [NSLocale preferredLanguages].firstObject;
return [UWConfig userLanguage] ? : @"zh-Hans";
}
+ (void)load
{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
//动态继承、交换,方法类似KVO,通过修改[NSBundle mainBundle]对象的isa指针,使其指向它的子类UWBundle,这样便可以调用子类的方法;其实这里也可以使用method_swizzling来交换mainBundle的实现,来动态判断,可以同样实现。
object_setClass([NSBundle mainBundle], [UWBundle class]);
});
}
@end
@implementation UWBundle
- (NSString *)localizedStringForKey:(NSString *)key value:(NSString *)value table:(NSString *)tableName
{
if ([UWBundle uw_mainBundle]) {
return [[UWBundle uw_mainBundle] localizedStringForKey:key value:value table:tableName];
} else {
return [super localizedStringForKey:key value:value table:tableName];
}
}
+ (NSBundle *)uw_mainBundle
{
if ([NSBundle currentLanguage].length) {
NSString *path = [[NSBundle mainBundle] pathForResource:[NSBundle currentLanguage] ofType:@"lproj"];
if (path.length) {
return [NSBundle bundleWithPath:path];
}
}
return nil;
}
@end
5、使用方式
当切换app语言的时候,先存储本地语言的设置;然后刷新界面即可。
- (IBAction)simplifiedChinese:(UIButton *)sender {
[UWConfig setUserLanguage:@"zh-Hans"];
// 刷新界面
[self reloadTabBarViewController];
}
- (IBAction)english:(UIButton *)sender {
[UWConfig setUserLanguage:@"en"];
// 刷新界面
[self reloadTabBarViewController];
}
刷新界面
我这儿是直接刷新了tabBar控制器。
- (void)reloadTabBarViewController {
UIStoryboard *storyBoard = [UIStoryboard storyboardWithName:@"Main" bundle:[NSBundle mainBundle]];
UITabBarController *tbc = [storyBoard instantiateInitialViewController];
// 跳转到个人中心页面(即设置语言的那个tabBarItem)
tbc.selectedIndex = self.tabBarController.selectedIndex;
// 创建设置页面
UIViewController *settingVC = [storyBoard instantiateViewControllerWithIdentifier:@"setting"];
settingVC.hidesBottomBarWhenPushed = YES;
// 创建语言选择界面
FiFLanguageController *languageVC = [storyBoard instantiateViewControllerWithIdentifier:@"chooseLanguage"];
languageVC.hidesBottomBarWhenPushed = YES;
UINavigationController *nvc = tbc.selectedViewController;
// 备用
NSMutableArray *vcs = nvc.viewControllers.mutableCopy;
[vcs addObjectsFromArray:@[settingVC, languageVC]];
//解决奇怪的动画bug。异步执行
dispatch_async(dispatch_get_main_queue(), ^{
//注意刷新rootViewController的时机,在主线程异步执行
//先刷新rootViewController
[UIApplication sharedApplication].keyWindow.rootViewController = tbc;
//然后再给个人中心的nvc设置viewControllers
nvc.viewControllers = vcs;
});
}
UIStoryboard *storyBoard = [UIStoryboard storyboardWithName:@"Main" bundle:[NSBundle mainBundle]];
UINavigationController *nvc = [storyBoard instantiateInitialViewController];
//设置NavigationBar隐藏
[nvc setNavigationBarHidden:YES];
// 创建语言选择界面
LanguageViewController *languageVC = [storyBoard instantiateViewControllerWithIdentifier:@"language"];
languageVC.hidesBottomBarWhenPushed = YES;
// 备用
NSMutableArray *vcs = nvc.viewControllers.mutableCopy;
[vcs addObjectsFromArray:@[ languageVC]];
//解决奇怪的动画bug。异步执行
dispatch_async(dispatch_get_main_queue(), ^{
//注意刷新rootViewController的时机,在主线程异步执行
//先刷新rootViewController
[UIApplication sharedApplication].keyWindow.rootViewController = nvc;
//然后再给个人中心的nvc设置viewControllers
nvc.viewControllers = vcs;
});