在我以前工作的地方,我们也遇到了这个问题。我们的应用程序被翻译成 10 种不同的语言。
起初,我们尝试按照 Wil 的建议去做,那就是让一切都变得超宽并适合每种语言。不幸的是,“在线备份”在英语中可能很短,但在其他语言(尤其是西班牙语)中,它真的很长(“copia de seguridad”只是意味着“备份”)。扩大我们的 UI 让一切看起来都非常糟糕。
有一天,我在玩一些 Core Animation 的东西并发现了这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
's 的 Y 位置和宽度与button1
's 相同。
在内部,CHLayoutManager
使用一个NSValueTransformer
计算新的定位信息。一些CHLayoutConstraint
初始化程序接受NSValueTransformer
,因此您可以创建任意复杂的布局操作。
我们使用它来约束和布局整个 UI,然后在代码中进行所有本地化(然后调用-sizeToFit
,并进行一些修改)。我们的 UI 将流入其最终布局。事实证明这非常方便。我们只需打包我们的.strings
文件,将它们发送给翻译人员,然后在我们取回它们时将它们放到适当的位置,我们的应用程序将立即针对该语言进行本地化。
CHLayoutManager
并不完美。它不能解决冲突,而只是按照添加的顺序应用约束。所以你可以用 42 种不同的方式来约束(例如)MinX
一个视图,但只会使用最后一种。此外,如果您约束 MinX 和 MaxX,它们也将按照添加的顺序应用,并且最终不会拉伸或缩小宽度。换句话说,约束视图的一个属性不会影响其他属性。它与 10.5+(GC 和非)兼容。然而,由于 Lion 的一些变化,我不太可能解决这些缺点。
尽管有这些缺点,但它是一个非常灵活的框架,并且(IMO)一些非常漂亮的代码。(另外,我调酒-[NSView dealloc]
!耶!)
更新
现在 AppKit 具有相同的功能(通过NSLayoutConstraint
),我建议使用该系统而不是CHLayoutManager
. 它更加健壮。