本地化基于xib的现代Mac应用程序

时间:2009-09-29 21:16:46

标签: cocoa macos localization xib

我们是由志愿者本地化的开源Mac应用程序。这些志愿者将在软件的特殊本地化版本(带有未剥离的笔尖)上完成工作,然后将更改发送给原始的xib和字符串文件。

问题在于,虽然有a way to integrate string changes without blowing away previous size changes,但我看不到集成新字符串和大小更改的方法(就像我们添加或替换视图时一样)。

我能看到的唯一方法就是让本地化程序直接使用原始xib并向我们发送差异。这意味着他们必须下载整个源代码,而不仅仅是该版本的可本地化版本,在Xcode和IB中工作,并自行运行diff命令(每个xib)或安装并使用Mercurial。

基于xib的应用程序有更好的方法吗?

4 个答案:

答案 0 :(得分:33)

更新 2014年1月:Apple的“自动布局”代码与其“基本”本地化内容相结合,充分利用了我的想法并对其进行了改进。我建议不要使用我在这个答案中谈到的旧工具。但是,男人也是我的权利!


我强烈建议强烈反对本地化中的帧更改。我知道这与Apple的建议背道而驰,但允许框架更改存在很多问题 - 你最终会遇到十亿个边缘案例。

想象一下,您的应用中有10个XIB,并且您支持12种语言。现在,你有120种不同的布局可以支持。你不能这样做。

更改字符串,将视图保留在原来的位置。如果需要,让所有语言都变得更大。听起来这应该不起作用,但确实如此。 (我用这种方式用10种左右的语言本地化了一个应用程序赢得了三个Apple设计奖。)

具体细节:

  • 对于广播和复选框,只需让它们向右延伸,超出最后一个英文字符。这也为不精确的鼠标提供了一个很好的大着陆区域。

  • 对于按钮,无论如何它们都应该是宽的,因为在按钮中间让文字变得狭窄似乎永远不会很好。

  • 对于tableview列上的标题,如果需要,您应该在加载时自动调整大小。

  • 对于解释性文字,您应该在右边有一些额外的空间,也许还有一行。它只是让XIB的英文版看起来不那么杂乱。当然,德国人会看到稍微紧张的XIB,但是,嘿,他们是德国人 - 他们可能已经习惯了。甚至可能还有一个德语单词。 “Deutscheninterfakkenclutterlongen。”

  • 如果文本字段居中,则只需在两侧添加相等的空格。没有理由不这样做。

我把它与脚本结合起来,这些脚本从我的XIB中取出所有字符串并将它们放在.strings文件中,然后在运行时动态地放回字符串,这样任何人都可以在没有任何特殊工具的情况下本地化我的应用程序。只需放入一堆.strings文件并运行它!

博客文章包括完整来源:[迷失在翻译中]¹。

答案 1 :(得分:3)

我承认我对Mac应用程序的本地化过程并不熟悉。但我确实遇到了一个脚本,它是Three20 iPhone library的一部分似乎可能有用:diffstrings.py是一个Python脚本,“将您的主要语言环境与所有其他语言环境进行比较,以帮助您确定哪个新的字符串需要翻译。它输出可以翻译的XML文件,然后合并回你的字符串文件。“

编辑:作为此问题的Wil Shipley's answer的随播广告,我将添加一个指向a blog post he just wrote的链接,其中详细介绍了本地化,并提供了一些他为缓解这一过程而建立的工具。

答案 2 :(得分:3)

我以前工作的地方也有这个问题。我们的应用程序被翻译成10种不同的语言。

起初,我们尝试做Wil所建议的,这是为了使一切都超宽,适合每种语言。不幸的是,“在线备份”在英语方面可能相当短,但在其他语言(尤其是西班牙语)中,它确实很长(“copia de seguridad”仅仅意味着“备份”)。扩大我们的UI使一切看起来都很糟糕。

有一天,我正在玩一些核心动画的东西并发现了CAConstraint类。 CAConstraint基本上是一种定义两个CALayers之间布局关系的方法。你给一个图层命名(比如“layerA”),然后说“layerB以某种方式被约束到一个名为layerA的兄弟图层”。然后,每当重新定位或调整名为layerA的图层时,layerB也会自动移动。它真的很整洁,而且正是我们所寻找的。

经过几天的工作,我想出了现在的CHLayoutManager。这基本上是对CAConstraint和朋友的重新制作,但对于NSViews。这是一个简单的例子:

CHLayoutConstraint * centerHorizontal = [CHLayoutConstraint constraintWithAttribute:CHLayoutConstraintAttributeMidX relativeTo:@"superview" attribute:CHLayoutConstraintAttributeMidX];
CHLayoutConstraint * centerVertical = [CHLayoutConstraint constraintWithAttribute:CHLayoutConstraintAttributeMidY relativeTo:@"superview" attribute:CHLayoutConstraintAttributeMidY];
[aView addConstraint:centerHorizontal];
[aView addConstraint:centerVertical];

这将使aView在其超级视图中居中,无论超级视图的大小如何调整。这是另一个:

[button1 setLayoutName:@"button1"];
[button2 addConstraint:[CHLayoutConstraint constraintWithAttribute:CHLayoutConstraintAttributeMinX relativeTo:@"button1" attribute:CHLayoutConstraintAttributeMaxX]];
[button2 addConstraint:[CHLayoutConstraint constraintWithAttribute:CHLayoutConstraintAttributeMaxY relativeTo:@"button1" attribute:CHLayoutConstraintAttributeMaxY]];
[button2 addConstraint:[CHLayoutConstraint constraintWithAttribute:CHLayoutConstraintAttributeWidth relativeTo:@"button1" attribute:CHLayoutConstraintAttributeWidth]];

这会使button2锚定在button1的右边缘,同时保持button2的Y位置和宽度与button1的相同。< / p>

在内部,CHLayoutManager使用NSValueTransformer来计算新的定位信息。一些CHLayoutConstraint初始值设定项接受NSValueTransformer,因此您可以创建任意复杂的布局操作。

我们使用它来约束和布局整个UI,然后在代码中进行所有本地化(随后调用-sizeToFit,并进行一些修改)。我们的UI将流入其最终布局。事实证明非常方便。我们只需打包我们的.strings文件,将它们发送给译员,然后在我们取回它们时将它们放到原位,我们的应用程序会立即针对该语言进行本地化。

CHLayoutManager并不完美。它不解决冲突,而只是按照添加的顺序应用约束。因此,您可以以不同的方式约束(例如)视图的MinX,但仅使用最后一种方式。此外,如果您约束MinX和MaxX,它们也将按照它们添加的顺序应用,并且不会最终拉伸或缩小宽度。换句话说,约束视图的一个属性不会影响其他属性。它与10.5+(GC和非)兼容。但是,由于Lion的一些变化,我不太可能解决这些缺点。

尽管存在这些缺点,但它是一个非常灵活的框架,而且(IMO)有一些非常漂亮的代码。 (另外,我调情-[NSView dealloc]!耶!)


更新

既然AppKit具有相同的功能(通过NSLayoutConstraint),我建议使用该系统而不是CHLayoutManager。它更强大。

答案 3 :(得分:0)

请记住,XIB文件只是一种模糊格式的XML文件,因此您可以轻松地翻译这些文件,前提是您可以找到首先要翻译的字符串。例如,这是创建名为Jenson的按钮的片段:

<object class="NSButtonCell" key="NSCell" id="41219959">
<int key="NSCellFlags">67239424</int>
<int key="NSCellFlags2">134217728</int>
<string key="NSContents">Jenson</string>
...
</object>

因此,您可以翻译该字符串,然后使用您的翻译值替换XIB中的字符串。为了验证它是否按预期工作,您可以将语言更改为使用随机键(例如BUTTON_TITLE),这样可以更容易地发现丢失的时间。

但是,项目的位置/大小是固定的,因此您可以使标题溢出以不同语言给出的空间。这就是为什么Mac为每种语言都有单独的XIB文件的原因之一,允许在逐个语言的基础上进行调整,无论如何难以维护。