iOS应用内语言切换功能

? 添加关注


作者

FarmGuo 2016.01.27 15:36*

写了6453字,被44人关注,获得了56个喜欢

iOS应用内语言切换功能

字数1372
阅读681
评论7
喜欢7

当我们的应用仅仅面向国内用户群,一般仅支持一种语言--中文就可以了。当面向国外用户时就需要进行国际化了,不仅仅是语言的转变,也可能包括设计风格,页面布局、交互效果的转变,如微信,微博,QQ这类应用都有着切换语言的功能。

iOS常用的国际化流程

1.建立strings文件。2.在Localization勾选支持的语言,在不同的后缀的同文件名的strings中设置标题。3.使用NSLocalizedStringFromTable(key, tbl, comment) 这个宏取出key对应的value。
这样的做法方便快捷,但有一些缺点。1.完全是根据手机系统设置的语言来进行国际化的。2.手机系统语言更改后,需将App Kill后,重新进入才有改变。可以看出给用户带来很大的不便,一些用户根本不知道如何设置语言,而且还去跳出应用,再Kill应用。我们需要的是应用内切换语言,所见即所得。

应用内切换语言

先看下微信的做法

111.gif

可以看出选择新语言,保存后就直接切换了。这样的用户体验就比较好了。

关键

1.NSBundle

An NSBundle object represents a location in the file system that groups code and resources that can be used in a program.NSBundle objects locate program resources, dynamically load and unload executable code, and assist in localization. You build a bundle in Xcode using one of these project types: Application, Framework, plug-ins.

2.宏 NSLocalizedStringFromTableInBundle

它的定义
#define NSLocalizedStringFromTableInBundle(key, tbl, bundle, comment) [bundle localizedStringForKey:(key) value:@"" table:(tbl)]
Returns a localized version of a string.The key for a string in the specified table.从指定的bundle里的table中返回对应key的值。
上面两点就是应用内切换的关键
先浏览下Demo架构

structure.png

使用storyboard方式,常见的TabBar+Navigation形式,第一个页面的按钮来切换语言,第二个来显示当前语言。

建立FGLanguageTool类来管理语言的切换,因为许多地方都要用到,将其设计为单例。并定义一个宏来加载设定的语言。

#define FGGetStringWithKeyFromTable(key, tbl)
[[FGLanguageTool sharedInstance] getStringForKey:key withTable:tbl]

#import <Foundation/Foundation.h>

@interface FGLanguageTool : NSObject

+(id)sharedInstance;

/**
 *  返回table中指定的key的值
 *
 *  @param key   key
 *  @param table table
 *
 *  @return 返回table中指定的key的值
 */
-(NSString *)getStringForKey:(NSString *)key withTable:(NSString *)table;

/**
 *  改变当前语言
 */
-(void)changeNowLanguage;

/**
 *  设置新的语言
 *
 *  @param language 新语言
 */
-(void)setNewLanguage:(NSString*)language;

@end

对应的.m文件

#define CNS @"zh-Hans"
#define EN @"en"
#define LANGUAGE_SET @"langeuageset"

#import "AppDelegate.h"
#import "FGLanguageTool.h"

static FGLanguageTool *sharedModel;

@interface FGLanguageTool()

@property(nonatomic,strong)NSBundle *bundle;
@property(nonatomic,copy)NSString *language;

@end

@implementation FGLanguageTool

+(id)sharedInstance
{
    if (!sharedModel)
    {
        sharedModel = [[FGLanguageTool alloc]init];
    }

    return sharedModel;
}

-(instancetype)init
{
    self = [super init];
    if (self)
    {
        [self initLanguage];
    }

    return self;
}

-(void)initLanguage
{
    NSString *tmp = [[NSUserDefaults standardUserDefaults]objectForKey:LANGUAGE_SET];
    NSString *path;
    //默认是中文
    if (!tmp)
    {
        tmp = CNS;
    }
    else
    {
        tmp = EN;
    }

    self.language = tmp;
    path = [[NSBundle mainBundle]pathForResource:self.language ofType:@"lproj"];
    self.bundle = [NSBundle bundleWithPath:path];
}

-(NSString *)getStringForKey:(NSString *)key withTable:(NSString *)table
{
    if (self.bundle)
    {
        return NSLocalizedStringFromTableInBundle(key, table, self.bundle, @"");
    }

    return NSLocalizedStringFromTable(key, table, @"");
}

-(void)changeNowLanguage
{
    if ([self.language isEqualToString:EN])
    {
       [self setNewLanguage:CNS];
    }
    else
    {
        [self setNewLanguage:EN];
    }
}

-(void)setNewLanguage:(NSString *)language
{
    if ([language isEqualToString:self.language])
    {
        return;
    }

    if ([language isEqualToString:EN] || [language isEqualToString:CNS])
    {
        NSString *path = [[NSBundle mainBundle]pathForResource:language ofType:@"lproj"];
        self.bundle = [NSBundle bundleWithPath:path];
    }

    self.language = language;
    [[NSUserDefaults standardUserDefaults]setObject:language forKey:LANGUAGE_SET];
    [[NSUserDefaults standardUserDefaults]synchronize];
    [self resetRootViewController];
}

//重新设置
-(void)resetRootViewController
{
    AppDelegate *appDelegate =
    (AppDelegate *)[[UIApplication sharedApplication] delegate];
    UIStoryboard *storyBoard = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
    UINavigationController *rootNav = [storyBoard instantiateViewControllerWithIdentifier:@"rootnav"];
    UINavigationController *personNav = [storyBoard instantiateViewControllerWithIdentifier:@"personnav"];
    UITabBarController *tabVC = (UITabBarController*)appDelegate.window.rootViewController;
    tabVC.viewControllers = @[rootNav,personNav];
}
@end

在ViewController里使用下面类似的方式进行赋值

self.navigationItem.title = FGGetStringWithKeyFromTable(@"RootTitle", @"Main");
self.languageLabel.text = FGGetStringWithKeyFromTable(@"NowLanguage", @"Person");

"Main","Person"就是strings文件的名字。"RootTitle"和"NowLanguage"就是key。

setting.png

这些就是我们的代码部分,还有一些资源文件要进行配置,就是我们的多语言文件。
1,添加支持的语言,选择工程。

add.png

点击Localizations区域的+号,添加新的语言,我们这里示例就选择简体中文。
2,建立strings文件
方法1.选择一个storyboard,这里我们使用工程默认的Main.storyboard,在File Inspecter。在Localization栏中勾选支持的语言。系统就会生成对应的文件。方法2.我们直接新建strings资源文件。在该文件的File Inspecter的Localization栏中勾选支持的语言。

strings.png

图中的Main是用方法1创建的,Person是用方法2创建的。这些同名的文件仅仅依靠后缀来区分,对应相应的资源。在这些文件中添加对应的key和value,如
Person.strings(English)文件中内容

"NowLanguage"="English";
"PersonTitle"="Person";

Person.strings(Chinese(Simplified))文件中内容

"NowLanguage"="中文";
"PersonTitle"="个人";

即在不同的相同文件名不同后缀名文件中设置不同的value。

几个关键点

1,当我们设置支持多语言后创建多语言文件后,工程文件结构中多了一些文件夹,Base是工程默认的,而后面的两个就是我们设置多语言后自动生成的,对应相应的英文和简体中文。分别以en和zh-Hans开头,所以FGLanguageTool中将中文和英文定义为en和zh-Hans来加载对应的bundle。

directory.png

里面存放的就是对应的strings文件

stings.png

2.NSLocalizedStringFromTableInBundle,从指定的bundle中去指定table的key的值。
3.更改语言后,重新设置rootViewController,使得可以重新加载语言。

最终效果

change.gif

? 添加关注


作者

FarmGuo 2016.01.27 15:36*

写了6453字,被44人关注,获得了56个喜欢

iOS应用内语言切换功能

字数1372
阅读681
评论7
喜欢7

当我们的应用仅仅面向国内用户群,一般仅支持一种语言--中文就可以了。当面向国外用户时就需要进行国际化了,不仅仅是语言的转变,也可能包括设计风格,页面布局、交互效果的转变,如微信,微博,QQ这类应用都有着切换语言的功能。

iOS常用的国际化流程

1.建立strings文件。2.在Localization勾选支持的语言,在不同的后缀的同文件名的strings中设置标题。3.使用NSLocalizedStringFromTable(key, tbl, comment) 这个宏取出key对应的value。
这样的做法方便快捷,但有一些缺点。1.完全是根据手机系统设置的语言来进行国际化的。2.手机系统语言更改后,需将App Kill后,重新进入才有改变。可以看出给用户带来很大的不便,一些用户根本不知道如何设置语言,而且还去跳出应用,再Kill应用。我们需要的是应用内切换语言,所见即所得。

应用内切换语言

先看下微信的做法

111.gif

可以看出选择新语言,保存后就直接切换了。这样的用户体验就比较好了。

关键

1.NSBundle

An NSBundle object represents a location in the file system that groups code and resources that can be used in a program.NSBundle objects locate program resources, dynamically load and unload executable code, and assist in localization. You build a bundle in Xcode using one of these project types: Application, Framework, plug-ins.

2.宏 NSLocalizedStringFromTableInBundle

它的定义
#define NSLocalizedStringFromTableInBundle(key, tbl, bundle, comment) [bundle localizedStringForKey:(key) value:@"" table:(tbl)]
Returns a localized version of a string.The key for a string in the specified table.从指定的bundle里的table中返回对应key的值。
上面两点就是应用内切换的关键
先浏览下Demo架构

structure.png

使用storyboard方式,常见的TabBar+Navigation形式,第一个页面的按钮来切换语言,第二个来显示当前语言。

建立FGLanguageTool类来管理语言的切换,因为许多地方都要用到,将其设计为单例。并定义一个宏来加载设定的语言。

#define FGGetStringWithKeyFromTable(key, tbl)
[[FGLanguageTool sharedInstance] getStringForKey:key withTable:tbl]

#import <Foundation/Foundation.h>

@interface FGLanguageTool : NSObject

+(id)sharedInstance;

/**
 *  返回table中指定的key的值
 *
 *  @param key   key
 *  @param table table
 *
 *  @return 返回table中指定的key的值
 */
-(NSString *)getStringForKey:(NSString *)key withTable:(NSString *)table;

/**
 *  改变当前语言
 */
-(void)changeNowLanguage;

/**
 *  设置新的语言
 *
 *  @param language 新语言
 */
-(void)setNewLanguage:(NSString*)language;

@end

对应的.m文件

#define CNS @"zh-Hans"
#define EN @"en"
#define LANGUAGE_SET @"langeuageset"

#import "AppDelegate.h"
#import "FGLanguageTool.h"

static FGLanguageTool *sharedModel;

@interface FGLanguageTool()

@property(nonatomic,strong)NSBundle *bundle;
@property(nonatomic,copy)NSString *language;

@end

@implementation FGLanguageTool

+(id)sharedInstance
{
    if (!sharedModel)
    {
        sharedModel = [[FGLanguageTool alloc]init];
    }

    return sharedModel;
}

-(instancetype)init
{
    self = [super init];
    if (self)
    {
        [self initLanguage];
    }

    return self;
}

-(void)initLanguage
{
    NSString *tmp = [[NSUserDefaults standardUserDefaults]objectForKey:LANGUAGE_SET];
    NSString *path;
    //默认是中文
    if (!tmp)
    {
        tmp = CNS;
    }
    else
    {
        tmp = EN;
    }

    self.language = tmp;
    path = [[NSBundle mainBundle]pathForResource:self.language ofType:@"lproj"];
    self.bundle = [NSBundle bundleWithPath:path];
}

-(NSString *)getStringForKey:(NSString *)key withTable:(NSString *)table
{
    if (self.bundle)
    {
        return NSLocalizedStringFromTableInBundle(key, table, self.bundle, @"");
    }

    return NSLocalizedStringFromTable(key, table, @"");
}

-(void)changeNowLanguage
{
    if ([self.language isEqualToString:EN])
    {
       [self setNewLanguage:CNS];
    }
    else
    {
        [self setNewLanguage:EN];
    }
}

-(void)setNewLanguage:(NSString *)language
{
    if ([language isEqualToString:self.language])
    {
        return;
    }

    if ([language isEqualToString:EN] || [language isEqualToString:CNS])
    {
        NSString *path = [[NSBundle mainBundle]pathForResource:language ofType:@"lproj"];
        self.bundle = [NSBundle bundleWithPath:path];
    }

    self.language = language;
    [[NSUserDefaults standardUserDefaults]setObject:language forKey:LANGUAGE_SET];
    [[NSUserDefaults standardUserDefaults]synchronize];
    [self resetRootViewController];
}

//重新设置
-(void)resetRootViewController
{
    AppDelegate *appDelegate =
    (AppDelegate *)[[UIApplication sharedApplication] delegate];
    UIStoryboard *storyBoard = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
    UINavigationController *rootNav = [storyBoard instantiateViewControllerWithIdentifier:@"rootnav"];
    UINavigationController *personNav = [storyBoard instantiateViewControllerWithIdentifier:@"personnav"];
    UITabBarController *tabVC = (UITabBarController*)appDelegate.window.rootViewController;
    tabVC.viewControllers = @[rootNav,personNav];
}
@end

在ViewController里使用下面类似的方式进行赋值

self.navigationItem.title = FGGetStringWithKeyFromTable(@"RootTitle", @"Main");
self.languageLabel.text = FGGetStringWithKeyFromTable(@"NowLanguage", @"Person");

"Main","Person"就是strings文件的名字。"RootTitle"和"NowLanguage"就是key。

setting.png

这些就是我们的代码部分,还有一些资源文件要进行配置,就是我们的多语言文件。
1,添加支持的语言,选择工程。

add.png

点击Localizations区域的+号,添加新的语言,我们这里示例就选择简体中文。
2,建立strings文件
方法1.选择一个storyboard,这里我们使用工程默认的Main.storyboard,在File Inspecter。在Localization栏中勾选支持的语言。系统就会生成对应的文件。方法2.我们直接新建strings资源文件。在该文件的File Inspecter的Localization栏中勾选支持的语言。

strings.png

图中的Main是用方法1创建的,Person是用方法2创建的。这些同名的文件仅仅依靠后缀来区分,对应相应的资源。在这些文件中添加对应的key和value,如
Person.strings(English)文件中内容

"NowLanguage"="English";
"PersonTitle"="Person";

Person.strings(Chinese(Simplified))文件中内容

"NowLanguage"="中文";
"PersonTitle"="个人";

即在不同的相同文件名不同后缀名文件中设置不同的value。

几个关键点

1,当我们设置支持多语言后创建多语言文件后,工程文件结构中多了一些文件夹,Base是工程默认的,而后面的两个就是我们设置多语言后自动生成的,对应相应的英文和简体中文。分别以en和zh-Hans开头,所以FGLanguageTool中将中文和英文定义为en和zh-Hans来加载对应的bundle。

directory.png

里面存放的就是对应的strings文件

stings.png

2.NSLocalizedStringFromTableInBundle,从指定的bundle中去指定table的key的值。
3.更改语言后,重新设置rootViewController,使得可以重新加载语言。

最终效果

change.gif

时间: 2024-10-19 07:32:29

iOS应用内语言切换功能的相关文章

Android应用内语言切换实现

自定义控件系列结束了,打个回马枪,补上前段时间埋下的一个坑---"应用内语言切换".APP语言改变是一个Configuration,但是这个Configuration和android手机屏幕旋转有点不大一样.屏幕旋转的时候,会destroy当前页面,并进行重新绘制.而切换语言后不会重新绘制页面,所以这种情况的出现造成了网上的一知半解小伙伴们哀声一片,不是在咒骂api的坑爹,就是在卖力的另辟蹊径想尽办法解决问题.思路都是很好的,目的也是坚决的,可是方向是错误的,把哥哥我也给带进了坑了,爬

Android应用语言切换功能

因为公司的产品大部分是销售到国外的,所以领导要求app有语言切换功能.我在网上搜了些相关知识并实现了功能,在这里做个中英文切换的demo记录下来. 先看看demo的效果: 效果就是这样子.当然也可以做成其他语言的切换,具体根据需求而定. 原理其实很简单,就是多个strings.xml进行切换然后在刷新Activity. 首先,在AndroidManifest.xml文件中的每个需要切换语言的Activity中加入android:configChanges="locale". 然后在re

Android app应用多语言切换功能实现

最近在做一个多语言切换的功能,类似于微信的语言切换,搜了下资料基本上都是以下这种: 1. 实现的效果 和微信类似,在设置界面打开切换语言的界面,选择语言后重启 HomeActivity,语言切换完成,下次重新打开 App ,也是用户设置的语言. 2. 实现步骤 1. 添加多语言文件 在不同的 value 文件夹下(例如 value .value-en.values-zh-rTW 文件夹)添加不同语言的 string.xml 文件,我们的项目添加了英文.简体中文.繁体中文三种语言,如下图所示: 其

iOS - 国际化语言切换

iOS国际化:如何切换语言 1.国际化就是将标签.提示信息等信息放到资源文件中,随着程序需要的语言提供对应的资源文件.以key/value对存储,每个资源的key值不变,value随着需求改变. 一般改变的都是写"死"的东西,网络请求的不能改变. 2.添加多语言: 新建工程(国际化)--> 国际化-->project-->info-->Localizations--> "+"Chinese(Simplified) --> fini

Android学习–Android app 语言切换功能

功能: app用户根据自己的语言喜好,设置app语言.语言设置只针对本app,并在下次启动应用时保留前一次启动设置. 更新语言: public static void changeAppLanguage(Resources resources, String lanAtr) { Configuration config = resources.getConfiguration(); DisplayMetrics dm = resources.getDisplayMetrics(); if (la

Android应用内语言切换实现(转)

使用Java反射机制 IActivityManager与ActivityManagerNative都是非公开类,使用Java反射去调用其中的方法. 第一步.使用Android开放的api更改Configuration,同时把语言类型保存下来 第二步.Destroy当前页面,重新绘制才能更改语言类型 如果你的页面不是首页,你调用上述代码只会更新当前页面,压在栈中的Activity依然不会更新界面.比如微信设置语言成功后,会自动跳转到首页,当然首页的内容也是更新后的,它的实现方式也很简单,与我们上面

Android 应用内多语言切换

p.p1 { margin: 0.0px 0.0px 12.0px 0.0px; line-height: 18.0px; font: 12.0px ".PingFang SC"; color: #000000 } p.p3 { margin: 0.0px 0.0px 13.9px 0.0px; line-height: 18.0px; font: 16.8px "PT Sans"; color: #000000 } p.p4 { margin: 0.0px 0.0

iOS程序框架设计之皮肤切换功能 (白天与夜间效果)

iOS程序框架设计之皮肤切换功能 一.引言 移动应用的开发中,有时我们会需要例如更换皮肤此类的功能,andorid采用xml配置UI的方式,这个问题或许还容易解决些,iOS的主要UI逻辑则是在代码中控制的,如果没有一个强大的框架方案,这个问题将变得非常棘手.网上也有很多诸如此类功能的优秀案例与框架,在这篇博客中,我与大家分享下我的解决方案,其中如果有不恰或者糟糕之处,希望与高人一起交流. 二.设计思路与框架 首先我的设计思路是采用通知的方式,原理可以如下理解为以下几步: 1.在系统的通知中心注册

iOS开发-多语言本地化和手动切换

App要国际推广,需要支持多语言.可以通过本地化语言和切换来实现.本工程可以不切换系统语言,不重启应用直接切换自定义语言.现在只写中英文,其他语言也是同样处理方法.如果支持语言多,切换时间也不会花长时间,瞬间成功切换. 1.创建工程项目 2.配置项目本地化支持简体中文和英文       工程-PROJECT-info->Localizations,点"+",选择(Chinese(Simplified))添加简体中文,英文Xcode自带有(English),所以不需要再次添加. 3