iOS应用内语言切换功能
发布日期:2021-05-07 16:19:14 浏览次数:23 分类:技术文章

本文共 5178 字,大约阅读时间需要 17 分钟。

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

iOS常用的国际化流程

1.建立strings文件。2.在Localization勾选支持的语言,在不同的后缀的同文件名的strings中设置标题。3.使用NSLocalizedStringFromTable(key, tbl, comment) 这个宏取出标题。

这样的做法方便快捷,但有一些缺点。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 
@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的值。

最终效果

change.gif

上一篇:UICollectionView的使用(一)
下一篇:图像Exif Orientation

发表评论

最新留言

网站不错 人气很旺了 加油
[***.192.178.218]2025年03月27日 19时23分19秒