iOS应用内语言切换功能
当我们的应用仅仅面向国内用户群,一般仅支持一种语言--中文就可以了。当面向国外用户时就需要进行国际化了,不仅仅是语言的转变,也可能包括设计风格,页面布局、交互效果的转变,如微信,微博,QQ这类应用都有着切换语言的功能。
iOS常用的国际化流程
1.建立strings文件。2.在Localization勾选支持的语言,在不同的后缀的同文件名的strings中设置标题。3.使用NSLocalizedStringFromTable(key, tbl, comment) 这个宏取出key对应的value。
这样的做法方便快捷,但有一些缺点。1.完全是根据手机系统设置的语言来进行国际化的。2.手机系统语言更改后,需将App Kill后,重新进入才有改变。可以看出给用户带来很大的不便,一些用户根本不知道如何设置语言,而且还去跳出应用,再Kill应用。我们需要的是应用内切换语言,所见即所得。
应用内切换语言
先看下微信的做法
![](http://upload-images.jianshu.io/upload_images/912738-d87cf9b3b1d25b26.gif?imageMogr2/auto-orient/strip)
可以看出选择新语言,保存后就直接切换了。这样的用户体验就比较好了。
关键
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架构
![](http://upload-images.jianshu.io/upload_images/912738-70349172392b55b9.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
使用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。
![](http://upload-images.jianshu.io/upload_images/912738-e14f6352d3880748.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
这些就是我们的代码部分,还有一些资源文件要进行配置,就是我们的多语言文件。
1,添加支持的语言,选择工程。
![](http://upload-images.jianshu.io/upload_images/912738-f0c63ff4f5931f4e.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
点击Localizations区域的+号,添加新的语言,我们这里示例就选择简体中文。
2,建立strings文件
方法1.选择一个storyboard,这里我们使用工程默认的Main.storyboard,在File Inspecter。在Localization栏中勾选支持的语言。系统就会生成对应的文件。方法2.我们直接新建strings资源文件。在该文件的File Inspecter的Localization栏中勾选支持的语言。
![](http://upload-images.jianshu.io/upload_images/912738-ebc585d86bf4af78.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
图中的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。
![](http://upload-images.jianshu.io/upload_images/912738-4f3bb58006ef5bdb.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
里面存放的就是对应的strings文件
![](http://upload-images.jianshu.io/upload_images/912738-ad31148f16fee24c.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
2.NSLocalizedStringFromTableInBundle,从指定的bundle中去指定table的key的值。
3.更改语言后,重新设置rootViewController,使得可以重新加载语言。
最终效果
![](http://upload-images.jianshu.io/upload_images/912738-60f7b13ab88437b1.gif?imageMogr2/auto-orient/strip)
原文链接:http://www.jianshu.com/p/627da5a9992c
著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”。
相关文章
- Airtest自动化测试实操案例 | iOS应用篇
- iOS中UITextField禁止粘贴
- iOS应用国际化(多语言支持)
- Step by Step Do IOS Swift CoreData Simple Demo
- iOS多线程之NSOperation和NSOperationQueue的使用
- iOS 11开发教程(六)iOS11Main.storyboard文件编辑界面
- 《iOS 9应用开发入门经典(第7版)》——第1章,第1.4节开发技术概述
- 《iOS 8应用开发入门经典(第6版)》——第1章,第1.6节小结
- 《iOS应用开发指南——使用HTML5、CSS3和JavaScript》——2.2 下载和安装iOS SDK
- iOS CGContextRef/UIBezierPath(绘图)
- Hello_IOS ios开发transform属性
- ios开发应用内实现多语言自由切换
- iOS开发之让你的应用“动”起来
- iOS开发UI篇—CAlayer层的属性
- Swift - 判断设备类型开发兼容的iOS应用(iPad使用分隔视图控制器)
- iOS 核心动画 Core Animation浅谈
- iOS App开发成本高背后的解释
- iOS SwiftUI 零基础之 GeometryReader 使用
- The Structure of an App-ios应用架构-MVC
- iOS 持续集成
- iOS应用内支付(内购)的个人开发过程及坑!
- iOS应用千万级架构:安全与加密
- ApplePay苹果支付准备工作:apple苹果IOS内购申请教程协议、税务和银行业务配置
- iOS应用id,套装id,appid,BundleID申请教程
- iOS开发-关于UITableView去掉粘性的问题
- iOS - 模拟器
- iOS全部150万应用归Win10?微软大计划