iOS 国际化(App内语言切换)[转]

原文链接://www.greatytc.com/p/66618c845107

想要实现App内的语言切换功能,那么首先要创建国际化语言文件,用于存储对应语言显示的文本。
1、创建国际化语言文件
command+N,选择Other里面的Empty文件。

image

我们将其命名为Localizable.strings
选中刚才创建的文件,在其右侧的的属性栏中点击Localize按钮。

image

2、设置项目需要支持的语言
选中project--->info--->Localization。
我们会发现里面默认有一个英语,我们可以点击左下角的➕号添加支持的语言。

image

点击+号,选择简体中文。

image

默认全选,点击完成即可:

image

这时我们展开Localizable.strings、Main.storyboard和LaunchScreen.storyboard,会看到多了一些文件。

image

3、文本国际化

image
image

大家看这个可能会有疑问,不知道是什么意思。
"首页" = "首页";
"首页" = "Homepage";
其实这两个是一个文本的不同语言的展示。“=”号左面的相当于key值;“=”号右面的相当于value值。不过为了使用方便,更容易理解,我这里直接使用了中文的内容作为key值。
使用方法的话:NSLocalizedString(@"首页", nil);
这样,在中文语言的时候返回“首页”(中文),在英文语言中返回“ Homepage”(英文)。

如果你是用xib或者Storyboard展示文本的话,想要文本国际化展示的话,需要另外的方法。

image

首先选中xib或者Storyboard,选中需要支持的语言。

image
image

我们可以看到对应的文件里面有对应的显示文本。如果要想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;
    });
}

ok,结束了!

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,561评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,218评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,162评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,470评论 1 283
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,550评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,806评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,951评论 3 407
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,712评论 0 266
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,166评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,510评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,643评论 1 340
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,306评论 4 330
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,930评论 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,745评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,983评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,351评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,509评论 2 348

推荐阅读更多精彩内容