本篇是斯坦福大学iOS7系列课程(CS193P)的最后一节课的总结,终于把18节课的内容都总结完了,而且这个文集也画上了句号,有点不舍的赶脚。。
好了,不煽情了,开始!
国际化 Internationalization
如果我们想要将app推广到国际市场,那么就免不了将我们的app翻译成其他国家的语言以便于当地人去使用。
而翻译的内容主要集中于“非内容”部分:例如标题类文字,按钮上的文字,提示框的文字等等。
所谓“翻译”app的过程主要分为国际化和本地化两个步骤:
- 国际化:是让app能够本地化的过程。
- 本地化:将程序翻译另外一种语言。
- 故事版字符串的本地化:改变故事版中出现的字符串。
- 类文件字符串的本地化:改变文件中出现的字符串,包括字符串面量和非字符串面量。
注意:
- 好的UI设计:给用户呈现出的内容大多数都需要显示的(内容),而不是自己添加的(提示)。这样一来,也会减少我们本地化的工作量。
- 所有的地方都要设置好自动布局,否则本地化将无从谈起,因为将文字翻译成其他语言后,长度很可能是不一样的。
下面来来具体看一下本地化的方法,分为故事版中字符串的本地化和类文件中字符串的本地化。
1. 故事版中的本地化
在故事版中本地化的过程是:
- 在项目里添加其他语言。
- 在被添加语言的故事版文件中找到相应的.string文件,加以更改。
具体过程如下图所示:
2. 类文件中字符串的本地化
除了需要本地化故事版中的字符串,类文件中的字符串也需要本地化,因为故事版并不能显示所有需要翻译的字符串。
而且,类文件中的字符串分为两种形式:
- 字符串面量。
- 非字符串面量。
所谓字符串面量,就是用@“”
语法包括起来的字符串:
NSString *myName = @“Jack”;
类似这样的字符串是比较好找的,只需要搜索@
即可很容易找到。
但是,我们仍然会通过该方法搜索到不应该本地化的字符串:
也就是不出现在UI中的字符串面量。
例如:
- 文件扩展名
- segure的identifier
- stiringWithFormat:
2.1字符串面量的本地化步骤:
- 找到需要本地化的字符串面量。
- 通过宏,将字符串面量添加到表中。
- 创建表的.string文件。
- 本地化.string文件
1.找到@"Sorry, this device cannot add a photo."
字符串面量。
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
if (![[self class] canAddPhoto]) {
[self fatalAlert:@"Sorry, this device cannot add a photo."]; //
} else {
[self.locationManager startUpdatingLocation];
}
}
2.通过宏,将字符串面量添加到表中。
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
if (![[self class] canAddPhoto]) {
[self fatalAlert:ALERT_CANT_ADD_PHOTO]; // @"Sorry, this device cannot add a photo."
} else {
[self.locationManager startUpdatingLocation];
}
}
#define ALERT_CANT_ADD_PHOTO NSLocalizedStringFromTable(@"ALERT_CANT_ADD_PHOTO", @"AddPhotoViewController", @"Alert message delivered when there is something that prevents the user from adding a new photo to the database that the user can do nothing about.")
3.创建表的.string文件
我们已经在AddPhotoViewController.m文件里将需要本地化的字符串添加到了叫做AddPhotoViewController的表里,下面就需要用命令行工具找到该.m文件:
4.本地化.string文件
在第三步中,我们需要手动创建AddPhotoViewController
表的.string文件,然后在文件内部将对应的key进行翻译。因为过程略繁琐,所以以动图的形式呈献给大家:
失误了,右侧的字符串应该是没有“@”的,大家注意。因为到最后才发现的,不好改了 额。。 理解万岁。。
2.2 非字面量字符串的本地化:
在类文件里,有些显示出来的字符串并不都是通过字符串面量赋值的,比如下面这个例子:
self.title = newfrc.fetchRequest.entity.name;
在这里,title取的是模型里的字段,并没有用字面量语法来表示。
对于这种情况,我们需要用NSBundle的localizedStringForKey:value:table:
方法来进行本地化。
self.title = [[NSBundle mainBundle] localizedStringForKey:newfrc.fetchRequest.entity.name
value:newfrc.fetchRequest.entity.name
table:@"Entities"];
这样一来,我们就生成了对应名字叫Entities的表的映射。但是这张表对应的.string文件还没有生成,需要我们手动去生成,并设置对应的key和value。生成方法如下所示:
设置页的UI
在苹果系统的设置里,会有我们装入的app的信息和设置。有时,我们需要将一些设置选项放在这里面供用户使用。
而这里的UI是通过通过Settings bundle来设定的。我们首先要新建一个Settings Bundle:
创建成功后,分别有一个slider,switch,和textfield来对应设置页里的UI。
在设置页里的样子是这样的:
那么如何使用呢?我们设置一下上一节课的Bouncer Demo的弹性系数:让用户通过调节设置里的slider来调整app里的弹性系数。
- (void)resetElasticity
{
//连接代码与Setting Bundle
NSNumber *elasticity = [[NSUserDefaults standardUserDefaults] valueForKey:@"Setting_Elasticity"];//连接setting bundle
if (elasticity) {
//如果有,就取当前设定的
self.elastic.elasticity = [elasticity floatValue];
} else {
//如果没有,就设置为1
self.elastic.elasticity = 1.0;
}
}
在这里,通过valueForKey
的键值对应了Setting Bundle plist 文件里的identifier
,我们将plist文件里的identifier
修改成了Setting_Elasticity
而且更改了Title
,而且将按钮和文本框删除掉,只保留了slider:
所对应的设置页的UI:
现在我们可以通过identifier连接了代码和plist文件,获取到了键对应的值。
而且,我们还需考虑在程序运行过程中,用户跳转到了设置页面来设置弹性系数的情况。因此,我们需要监听用户是否更改了设置里的选项:
监听用户在设置中的行为:
[[NSNotificationCenter defaultCenter] addObserverForName:NSUserDefaultsDidChangeNotification
object:nil
queue:nil
usingBlock:^(NSNotification *note) {
[self resetElasticity];
}];
最后的话
当当当当!
笔者终于利用了2个月的部分业余时间总结了所有斯坦福iOS7的课程和相关Demo。通过以博客的形式总结,更加加深了对知识的理解和认识,也对基础知识进行了一次查缺补漏,或许也在一定程度上给其他看到这些博客的同仁们一些帮助吧~
最后附上这一系列笔者总结的所有Demo在GitHub上的地址:Stanford_iOS_Lecture_DemoBundle。
本文已在版权印备案,如需转载请访问版权印。48422928
获取授权
-------------------------------- 2018年7月17日更新 --------------------------------
注意注意!!!
笔者在近期开通了个人公众号,主要分享编程,读书笔记,思考类的文章。
- 编程类文章:包括笔者以前发布的精选技术文章,以及后续发布的技术文章(以原创为主),并且逐渐脱离 iOS 的内容,将侧重点会转移到提高编程能力的方向上。
- 读书笔记类文章:分享编程类,思考类,心理类,职场类书籍的读书笔记。
- 思考类文章:分享笔者平时在技术上,生活上的思考。
因为公众号每天发布的消息数有限制,所以到目前为止还没有将所有过去的精选文章都发布在公众号上,后续会逐步发布的。
而且因为各大博客平台的各种限制,后面还会在公众号上发布一些短小精干,以小见大的干货文章哦~
扫下方的公众号二维码并点击关注,期待与您的共同成长~