我有一个课程,实现了我们都知道和喜爱的“拍照/从图书馆中选择”。它在这里https://github.com/fulldecent/FDTake这通过git submodule包含在我的其他项目中,并且工作正常。
现在我需要将该课程中的文本翻译成中文,因此它是“拍照/选照片”或类似的东西。是否有一种很好的方式将翻译放在那里,以便每个人都可以使用它们?
答案 0 :(得分:5)
本地化通常由NSLocalizedString(<#key#>, <#comment#>)
宏处理。在源代码中,用宏替换所有硬编码字符串。例如:
[self.buttonTitles addObject:@"Hi"]; // hard coded greeting
带
[self.theLabel setText:(NSLocalizedString(@"theKey", @"Hi"))];
然后genstrings
(来自终端内)用于扫描实现文件(* .m)并将其输出写入语言项目文件夹(此处:en.lproj)
$ genstrings -o en.lproj/ *.m
在目录en.lproj/
中有一个名为Localizable.strings
的文件。其内容将是:
/* Hi */
"theKey" = "theKey";
评论/* Hi */
取自我们的源代码。字符Hi
应显示给(讲英语的)用户。因此,我们需要编辑等号右侧的字符串并将其设为问候语,= "theKey"
必须成为= "Hi"
:
/* Hi */
"theKey" = "Hi!";
如果只有几个字符串或者没有打算修改字符串,那么这一切都很好。当gestrings再次运行时,它将覆盖修改,你实际上会失去Localizable.strings
中完成的工作。
一个想法可能是将genstrings的输出写入不同的位置。但是,您必须手动合并更改。在Localizable.strings
文件增长后,尝试保持源代码和Localizable.strings
同步变成了一场噩梦。所以我们尽量避免这种情况。
使用NSLocalizedStringWithDefaultValue(<#key#>, <#tbl#>, <#bundle#>, <#val#>, <#comment#>)
可以带来很大的帮助。此宏将允许在Localizable.strings
文件中设置默认值,此外,它将使得对值字段的初始编辑的需要消失。
把它放在一起:
[self.theLabel setText:NSLocalizedStringWithDefaultValue(@"theKey2", @"Localizable", [NSBundle mainBundle], @"Hi!", @"informal greeting"))];
在运行上面使用的genstrings
命令之后,Localizable.strings
/* informal greeting */
"theKey2" = "Hi!";
除了现在告诉翻译我们想要非正式问候语的评论之外,“Hi!”
已存在于价值提交中。无需转到Localizable.strings文件,搜索正确的行,将字段“theKey”修改为“Hi!”。 genstrings
根据NSLocalizedStringWithDefaultValue提供的默认值为我们做了这个。
将文件Localizable.strings
添加到xcode项目中。
更改源代码后,对于Xcode内部的新语言,首先将本地化添加到Localizable.strings
。 Xcode将根据原始Localizable.strings
在子文件夹下生成Localizable.strings
的副本。
我个人不会说中文,而是说德语。因此,如果要添加德语本地化,我的翻译将位于de.lproj/Localizable.strings
下,意大利语位于it.lproj/
下,依此类推。
根据需要修改新的Localizable.strings
:
(德语)
/* informal greeting */
"theKey2" = "Hallo!";
(意大利)
/* informal greeting */
"theKey2" = "Ciao!";
然后构建并运行。
********* begin edit
以上考虑了“标准”xcode项目。您在询问是否批量模拟模块,因此允许您的代码成为项目的补充。我建议你创建一个包含本地化的包。当有人将您的代码包含到他们的项目中时,本地化将保持独立。 有关包的完整文档是here。
使用捆绑包进行本地化的项目是QuincyKit(可能还有更多,这是第一个想到的)
因此,当将本地化放入除mainBundle
之外的其他包中时,下面一行中的[NSBundle mainBundle]
必须更改
[self.theLabel setText:NSLocalizedStringWithDefaultValue(@"theKey2", @"Localizable", [NSBundle mainBundle], @"Hi!", @"informal greeting"))];
不是从mainBundle获取字符串,而是获取对自己模块的引用。文档建议:
NSBundle* myBundle = [NSBundle bundleForClass:[self class]];
因此该行变为:
[self.theLabel setText:NSLocalizedStringWithDefaultValue(@"theKey2", @"Localizable", myBundle, @"Hi!", @"informal greeting"))];
********* end edit
答案 1 :(得分:1)
我认为捆绑(如Olaf建议的那样)可以很好地工作,但另一种方法是减少开销以确保可本地化的字符串资源不会干扰同一解决方案中的另一个项目(causing a weird problem to people reusing your component in another localized project)您的localizable.strings
文件名为唯一的文件名。这意味着您使用NSLocalizedString
的位置现在需要使用其变体NSLocalizedStringFromTable
(Apple documentation),其中tableName与您的字符串文件同名(不带.strings扩展名)。您可以定义自己的宏,这样就可以直接替换NSLocalizedString
,例如FDTakeLocalizedString
。
与localizable.strings
文件相比,XIB文件或故事板发生文件名冲突的可能性要小得多。但在这两种情况下,如果使用带前缀的命名约定(比如FDTake.strings和FDTake-Main.xib),它将消除风险并且只能帮助。