美文网首页
iOS APP 内部切换语言

iOS APP 内部切换语言

作者: Poseidong | 来源:发表于2017-11-22 00:07 被阅读0次

    前言:相信大家都看过很多关于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

    相关文章

      网友评论

          本文标题:iOS APP 内部切换语言

          本文链接:https://www.haomeiwen.com/subject/qkbgmxtx.html