不同目标的故事板本地化

12

我有一个项目有3个目标。每个目标只需要支持一种语言,但不同的目标需要支持不同的语言。目前我有:

  • 目标1(西班牙语)
  • 目标2(西班牙语)
  • 目标3(葡萄牙语)

我的大部分字符串都在Localizable.strings文件中,我为每个目标简单地针对不同的文件进行定位。但是,一些字符串在我的storyboard文件中。问题是似乎无法为每个目标创建不同的故事板本地化文件。如果我更改了葡萄牙语文件的定位,则西班牙语文件的定位会自动更改。

一个可能的解决方案是为每个目标复制一个Storyboard,但随着目标数量的增加,这种方法并不可扩展。我也可以在每个视图控制器中使用NSLocalizedString修改所有文本,但这似乎很繁琐且容易出错。

是否有更好的解决方案?


1
可能需要在这个问题上放一个xCode标签,因为答案很可能是某种xCode设置。 - NSGangster
3个回答

9

在多个目标中共享Storyboard

尽管这篇答案是首选方法,但是你可以为不同的目标分配不同的Storyboard本地化,并在所有目标之间共享相同的Storyboard。

前提条件:

按照这篇答案中的说明进行操作。

概念:

您希望在每个目标中都有Main.storyboard,但是在每个目标中都有不同的Main.strings。此外,您不希望每个目标都可用的所有本地化都可用。

要实现这一点,您必须直接操作.lproj,这是仅使用文件检查器时隐藏的过程。

步骤:

  1. 按照这篇答案中的步骤创建所有组件。
  2. 从任何一个目标中删除Main.storyboard。当然,选择Remove Reference以保留Storyboard。
  3. 在Finder中找到Base.lproj。将Main.storyboard拖放回您的项目,并选择每个目标。
  4. 在文件检查器中,确保未选中语言,并且仍然使用Localizable Stringsenter image description here
  5. 再次在Finder中找到en.lprojes.lprojfr.lproj等。请注意,它们都包含Main.strings的版本。将这些.lproj(整个目录)拖回到您的项目中。这一次,不要选择任何目标。
  6. 最后,在文件检查器中,将每个Main.strings与所需的目标关联。对于每个.strings重复此步骤。 enter image description here

结论

通过将中的.lproj.storyboard解耦,您可以自由地关联文件和目标。

演示:

在将语言设置为“Français”的设备上使用法语目标进行操作:

iPhone 4上的法语示例


► 在GitHub中找到此解决方案,并在Swift Recipes中获取更多详细信息。


我尝试过这个,但它没有起作用。虽然.strings文件已正确添加到目标中,但是Storyboard并没有读取它们。.strings文件的内容从未被使用过;我只能看到原始Storyboard中的任何文本。 - Martin Epsz
如果您的目标语言在设备上不可用,可能会发生这种情况。请确保您在设备上进入设置,并选择您要针对的语言。我已经添加了一个屏幕截图和一个实际的Xcode项目,供您验证我的帖子是准确的,并且我概述的技术已经得到验证和测试。 - SwiftArchitect
但是目标并不仅提供一种语言。这个答案比其他答案好一点,因为每个目标支持基础语言加目标语言,而不是所有语言,但它仍然没有解决原始问题。 - Martin Epsz
每个目标都支持基本语言和目标语言,而不是所有语言:这难道不正是您要做的吗?如果您不想重复故事板,则必须使用基础。根据定义,“本地化”意味着“以首选语言运行”。如果您希望您的应用程序在任何操作系统中运行,比如说,世界语,那么您不能使用任何本地化支持;您必须用世界语创建您的应用程序。这就是后编译脚本和plist操纵脚本发挥作用的时候。 - SwiftArchitect
1
不好意思,如果问题读起来是这样的话,我的回答是否定的。每个目标必须只能用一种语言。 - Martin Epsz

7

跨目标共享本地化

  1. 假设您的项目中已经有多种语言,在项目导航器中选择您的故事板(比如Main.storyboard

  2. 文件检查器 下的本地化选项卡中添加英语。选择默认的可本地化字符串,这将为每种语言创建一个Main.string文件,并将您的故事板跨语言共享。

    Create a Main.strings

  3. 仅需点击第2步中的复选框即可添加该语言的Main.string (English)文件,专门用于该Main.Storyboard的语言本地化。请特别注意新层次结构,这些不是Localizable.strings,而是从Main.storyboard派生的Main.strings

    New localizations per Storyboard

  4. 在每个语言文件中进行本地化。

例如,从将信息显示为世界语UILabel开始,在设备以英语运行时,其将显示为英文:

/* Class = "UILabel"; text = "Tiu mesaĝo estas en Esperanto"; ObjectID = "acC-pA-eMt"; */
"acC-pA-eMt.text" = "This message is in English";

从这里开始为您的项目添加多种语言:

如果您需要添加更多语言,请按照以下步骤操作:

  1. 项目导航器中选择您的项目

  2. 项目和目标列表中,再次选择该项目

    选择项目

  3. 选择信息选项卡

  4. 本地化下,保持使用基础国际化 (除非您的UI本身必须跨语言更改)

  5. 点击+,选择一种新语言。在呈现给您的对话框中,选择您想要为其添加多个本地化的每个Storyboard。

    选择要本地化的Storyboard

如果您在第5步中错过了Storyboard,则可以通过按照假设您已经拥有多种语言中的步骤,轻松地将新语言添加到Storyboard中。


这使得每个目标都支持所有语言。但正如我所说,每个目标只需要支持一种语言。 - Martin Epsz
一旦 Main.strings 存在,您可以按目标挑选所需的字符串。多个目标会创建多个可执行文件(例如每种语言一个),这与单个多语言应用程序非常不同。实质上,您并没有本地化您的应用程序,而是在创建多个应用程序。 - SwiftArchitect
不行。至少在XCode 7中,如果我将葡萄牙语的Main.strings添加到目标3中,则所有其他的Main.strings都会自动添加到同一个目标中。即使那样能够工作,由于我已经向我的项目添加了本地化,因此所有的目标都将被标记为具有本地化,而实际上它们并没有本地化。当我发布我的应用程序时,这将是一个问题。 - Martin Epsz
好的观点。我已经创建了https://dev59.com/o1sX5IYBdhLWcg3whv7Q#33791181来解决`.lproj`的问题,并明确说明目标关联。 - SwiftArchitect
有什么办法可以为每个目标拥有不同的Main.strings文件?换句话说,使用一个故事板但为每种语言使用不同的Main.Strings文件。@SwiftArchitect - hasan
我不记得了,但我认为我找不到解决方案。 - hasan

0
你所需要的是:为你的应用程序创建一个常见的Xcode工作区,然后为你的语言集合创建主Xcodeproj文件的副本,并为它们创建不同的目标。接着,你可以在新的Xcodeproj中为每个项目设置语言。此外,你还可以轻松调整构建阶段的“复制包资源”等其他设置。我使用这种方法。如果在将项目添加到工作区时出现Xcode崩溃,请使用Xcode打开项目,重命名它并重命名或复制目标(我认为相同的名称会导致此问题)。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接