前言:网络上关于iOS国际化的文章很多,但基本上都是基于跟随系统语言的国际化,笔者就不赘述了-0 –

今天要讲的是不跟随系统的切换语言版本方案,即程序内部的切换语言版本方案。

一、总则:

应用内部语言不跟随系统语言,由应用自己进行控制,通过配置多个语言文件,根据用户的选择动态获取不同文件夹下的语言文件,显示在界面上。

最后把用户选择的语言持久化到本地,下次运行时读取。

二、应用内的国际化

1、新建工程

新建Single View Application工程,取名为MyInternational。

2、添加多语言文件

我们选择使用自己的语言文件,而不是系统的localizable.string,因为在项目开发使用svn时,多人操作同一文件可能会造成冲突。

在Resource中添加新的Strings File:

取名为hello(记得Targets要勾选项目)

新建完成之后会生成hello.string文件,把它拖进Supporting Files里。

3、配置hello.string国际化

首先配置刚才的hello.string文件。

点击hello.strings文件,点击圈中的Make localized(本地化)。

只有English,没关系点击确定。

4、配置项目国际化

网络上很多配置方法不靠谱,因为新版的Xcode位置“+”号的位置换了,这里教大家正确的方法,点击项目—>选择Project—>选择Info—>点击“+”号。

点击“+”号后,添加中文,当然也可以添加其他的语言,弹出对话框,infoPlist是配置系统的国际化文件,可以配置图标之类的多语言环境,不属于本文范围,nib文件看需要配,这里选择不配。

配置完成之后,再看hello.string便分成了两个文件。

完成上面的四步便完成了项目内的多语言环境配置,下面来看看代码怎么写。

5、添加需要的字符串

分别在hello.strings(English)与hello.strings(Chinese)里面添加对应语言的字符串。

字符串的格式为“key”=“value”;键值对(别忘记分号!)

接下来配置项目需要的字符串,一个用于lable的显示,一个用于button的显示。

hello.strings(English)

"invite" ="hello atany,come to join in us!";

"buttonInfo" ="change Language";

hello.strings(Chinese)

"invite" ="你好 atany,快来加入我们吧!";

"buttonInfo" ="切换语言";

6、看看流程

【实现思路:】

在初始化首个Controller的时候,进行应用语言的加载。首次加载因为userLanguage(应用内语言)不存在,则使用系统当前的语言,保存到userlanguage,下次直接读。读出来之后,获取到对应文件路径,得到文件的索引,储存到工具类InternationalControl的静态变量bundle中。

其他地方需要用字符串时,用工具类获得bundle即可读取相应文件中的字符串。

7、新建工具类InternationalControl

InternationalControl.h

  1. #import <Foundation/Foundation.h>
  2. #import <UIKit/UIKit.h>
  3. @interface InternationalControl : NSObject
  4. +(NSBundle *)bundle;//获取当前资源文件
  5. +(void)initUserLanguage;//初始化语言文件
  6. +(NSString *)userLanguage;//获取应用当前语言
  7. +(void)setUserlanguage:(NSString *)language;//设置当前语言
  8. @end

InternationalControl.m

1)创建静态变量bundle,以及获取方法bundle(注:此处不要使用getBundle)。

  1. static NSBundle *bundle = nil;
  2. + ( NSBundle * )bundle{
  3. return bundle;
  4. }

2)初始化方法:

userLanguage储存在NSUserDefaults中,首次加载时要检测是否存在,如果不存在的话读AppleLanguages,并赋值给userLanguage。

  1. +(void)initUserLanguage{
  2. NSUserDefaults *def = [NSUserDefaults standardUserDefaults];
  3. NSString *string = [def valueForKey:@"userLanguage"];
  4. if(string.length == 0){
  5. //获取系统当前语言版本(中文zh-Hans,英文en)
  6. NSArray* languages = [def objectForKey:@"AppleLanguages"];
  7. <pre class="cpp" name="code">        NSString *current = [languages objectAtIndex:0];
  8. string = current;
  9. [def setValue:current forKey:@"userLanguage"];
  10. [def synchronize];//持久化,不加的话不会保存
  11. }
  12. //获取文件路径
  13. NSString *path = [[NSBundle mainBundle] pathForResource:string ofType:@"lproj"];
  14. bundle = [NSBundle bundleWithPath:path];//生成bundle
  15. }
  16. </pre>

3)获得当前语言方法

  1. +(NSString *)userLanguage{
  2. NSUserDefaults *def = [NSUserDefaults standardUserDefaults];
  3. NSString *language = [def valueForKey:@"userLanguage"];
  4. return language;
  5. }

4)设置语言方法

  1. +(void)setUserlanguage:(NSString *)language{
  2. NSUserDefaults *def = [NSUserDefaults standardUserDefaults];
  3. //1.第一步改变bundle的值
  4. NSString *path = [[NSBundle mainBundle] pathForResource:language ofType:@"lproj" ];
  5. bundle = [NSBundle bundleWithPath:path];
  6. //2.持久化
  7. [def setValue:language forKey:@"userLanguage"];
  8. [def synchronize];
  9. }

8、拖nib,配置点击事件

一个button,一个label,button用于切换语言,label用于显示信息。

9、配置加载的第一个Controller,这里是YGViewController

YGViewController.h

  1. #import <UIKit/UIKit.h>
  2. @interface YGViewController : UIViewController
  3. @property (retain, nonatomic) IBOutlet UILabel *inviteLabel;//label
  4. - (IBAction)changeLanguage:(id)sender;//点击事件
  5. @property (retain, nonatomic) IBOutlet UIButton *btChange;//button
  6. @end

 

YGViewController.m

1)加载:

  1. - (void)viewDidLoad
  2. {
  3. //注册通知,用于接收改变语言的通知
  4. [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(changeLanguage) name:@"changeLanguage" object:nil];
  5. [InternationalControl initUserLanguage];//初始化应用语言
  6. NSBundle *bundle = [InternationalControl bundle];
  7. NSString *inviteMsg = [bundle localizedStringForKey:@"invite" value:nil table:@"hello"];
  8. NSString *buttonInfo = [bundle localizedStringForKey:@"buttonInfo" value:nil table:@"hello"];//table为hello.string的文件名
  9. [_btChange setTitle:buttonInfo forState:UIControlStateNormal];
  10. _inviteLabel.text = inviteMsg;
  11. [super viewDidLoad];
  12. }

2)点击修改语言方法

  1. - (IBAction)changeLanguage:(id)sender {
  2. NSString *lan = [InternationalControl userLanguage];
  3. if([lan isEqualToString:@"en"]){//判断当前的语言,进行改变
  4. [InternationalControl setUserlanguage:@"zh-Hans"];
  5. }else{
  6. [InternationalControl setUserlanguage:@"en"];
  7. }
  8. //改变完成之后发送通知,告诉其他页面修改完成,提示刷新界面
  9. [[NSNotificationCenter defaultCenter] postNotificationName:@"changeLanguage" object:nil];
  10. }

3)接收到通知执行方法,刷新界面

  1. -(void)changeLanguage{
  2. [_btChange setTitle:[[InternationalControl bundle] localizedStringForKey:@"buttonInfo" value:nil table:@"hello"] forState:UIControlStateNormal];
  3. _inviteLabel.text =[[InternationalControl bundle] localizedStringForKey:@"invite" value:nil table:@"hello"];
  4. }

如果有多个界面的话,需要每个界面都配置接收通知,用于修改界面。

10、运行界面

可以看到点击切换语言之后,语言切换成功。

退出程序再次进入,保留了上次选择的语言。

iOS 应用程序内部国际化,不跟随系统语言的更多相关文章

  1. [置顶] iOS 应用程序内部国际化,不跟随系统语言

    前言:网络上关于iOS国际化的文章很多,但基本上都是基于跟随系统语言的国际化,笔者就不赘述了-0 – 今天要讲的是不跟随系统的切换语言版本方案,即程序内部的切换语言版本方案. 一.总则: 应用内部语言 ...

  2. IOS APP 国际化(实现不跟随系统语言,不用重启应用,代码切换stroyboard ,xib ,图片,其他资源)

    http://www.cnblogs.com/tangbinblog/p/3898046.html

  3. 【转】在企业内部分发 iOS 应用程序

    (via:破船之家,原文:Provision iOS IPA App for In-House Enterprise Distribution)   在企业内部分发 iOS 应用程序非常复杂.经过努力 ...

  4. iOS多语言(国际化)开发(尾随系统 + APP内手动设置)

    一:尾随系统切换语言 1>创建好项目project后, 新建一个多语言文件: 2>加入要设置的语言类型: 3>加入成功 细心的朋友可能会发如今English后面写的是3 Files ...

  5. iOS - 应用程序国际化

    开发的移动应用更希望获取更多用户,走向世界,这就需要应用国际化,国际化其实就是多语言.这篇文章介绍Xcode4.5以后的国际化,包括应用名国际化和应用内容国际化.如果是Xcode4.5之前版本请参考. ...

  6. ios应用程序国际化

    1.程序名称国际化: 在Xcode中新建项目后,能够在project的info选项卡中找到Localization的项目,能够加入应用程序须要支持的国际语言. 回到项目中能够发如今InfoPlist. ...

  7. iOS应用程序工程文件以及启动流程

    转载请标明出处: http://blog.csdn.net/xmxkf/article/details/51351188 本文出自:[openXu的博客] iOS程序启动流程 完整启动流程 UIApp ...

  8. iOS app 程序启动原理

    iOS app 程序启动原理 Info.plist: 常见设置     建立一个工程后,会在Supporting files文件夹下看到一个"工程名-Info.plist"的文件, ...

  9. 浅析 - iOS应用程序的生命周期

    1.应用程序的状态 状态如下: Not running  未运行  程序没启动 Inactive          未激活        程序在前台运行,不过没有接收到事件.在没有事件处理情况下程序通 ...

随机推荐

  1. bzoj3462: DZY Loves Math II

    状态很差脑子不清醒了,柿子一直在推错.... ... 不难发现这个题实际上是一个完全背包 问题在于n太大了,相应的有质数的数量不会超过7个 假设要求sigema(1~plen)i pi*ci=n 的方 ...

  2. let 命令 与 var的区别

    ES6 新增了let命令,用来声明变量.它的用法类似于var,但是所声明的变量,只在let命令所在的代码块内有效. <script> { let a = 10; var b = 1; } ...

  3. 一步一步学Silverlight 2系列(16):数据与通信之JSON

    概述 Silverlight 2 Beta 1版本发布了,无论从Runtime还是Tools都给我们带来了很多的惊喜,如支持框架语言Visual Basic, Visual C#, IronRuby, ...

  4. 用HTTP操作和文件操作把网页下载到sd卡

    这里先把代码贴到这里做一个存档,写到SD卡的是一个txt文件,改成HTML格式之后会出现百度主页,但是中文是乱码,这一点先暂时不去研究了. 代码: package com.larry.gotcha; ...

  5. idea类名下有红色波浪线

    能编译通过说明SDK导入正确,但是为啥我们点击每一个Java文件会出现好多红色的下划线 ,并提示idea cant resolve symbol 原因就是可能没有清除原来的历史缓存,导致一些错误,解决 ...

  6. 图的理解:深度优先和广度优先遍历及其 Java 实现

    遍历 图的遍历,所谓遍历,即是对结点的访问.一个图有那么多个结点,如何遍历这些结点,需要特定策略,一般有两种访问策略: 深度优先遍历 广度优先遍历 深度优先 深度优先遍历,从初始访问结点出发,我们知道 ...

  7. A - Mike and Fax

    Time Limit:1000MS     Memory Limit:262144KB     64bit IO Format:%I64d & %I64u Description While ...

  8. java web url编码解码问题(下载中文名文件)

    问题描述:需要url直接访问中文名的文件,类似于在地址栏里直接输入http://localhost:8080/example/丽江旅游攻略.doc 来进行文件下载,tomcat的server.xml文 ...

  9. Eclipse中,open declaration;open implementation;open super implementation的区别

    open declaration:是打开该方法的接口文件(一般没实在意义,只是简单一句):open implementation:是打开具体实现该方法的类文件(具体逻辑的处理地方,方法的主要实现的地方 ...

  10. Codeforces Round #408 (Div. 2) D. Police Stations(最小生成树+构造)

    传送门 题意 n个点有n-1条边相连,其中有k个特殊点,要求: 删去尽可能多的边使得剩余的点距特殊点的距离不超过d 输出删去的边数和index 分析 比赛的时候想不清楚,看了别人的题解 一道将1个联通 ...