如何让自动布局自动将NSTextField换行为NSTextField的宽度更改为多行?使用自动布局自动换行NSTextField
我有许多NSTextField在检查器窗格中显示静态文本(即:标签)。由于用户调整了检查器窗格的大小,因此如果需要,我希望右侧标签可以重新排列成多行。
(Finder的获取信息面板做到这一点。)
但我一直无法弄清楚的自动布局约束的组合,以允许这种行为。在所有情况下,右侧的NSTextFields拒绝包装。 (除非我明确添加允许的高度约束)
视图层次结构是这样的:每个灰色带都是包含两个NSTextField的视图,左侧的属性名称和右侧的属性值。当用户调整检查器窗格的大小时,我希望属性值标签根据需要自动调整其高度。
现状:
我想什么有发生:
(请注意,这种行为比大多数堆栈溢出问题,不同的我遇到关于NSTextFields来到和自动布局,这些问题希望文本字段在用户输入时增长,在这种情况下,文本是静态的,并且NSTextField被配置为查看就像一个标签。)
更新1.0
以@ hamstergene的建议下,我子类的NSTextField,并提出了小样本应用程序。大多数情况下,它现在可以工作,但现在有一个小的布局问题,我怀疑是由于NSTextField的框架与自动布局所期望的不完全同步的结果。在下面的屏幕截图中,右侧标签全部在垂直方向上间隔排列,约束条件为top
。当窗口调整大小时,Where
字段得到正确调整和包装。然而,Kind
文本字段不会被推下来,直到我调整窗口“多一个像素”。
例子:如果我调整窗口的大小,以恰到好处的宽度,该文本框Where
做它的第一个包,然后我得到的中间图像中的结果。如果我调整窗口的大小再多一个像素,那么Kind
字段的垂直位置就会被正确设置。
我怀疑这是因为自动布局正在通过,然后帧被明确设置。我想象一下,自动布局并没有看到那次通过,而是在下一次通过时做到这一点,并相应地更新位置。
假设是这个问题,我如何通知setFrameSize
我正在做这些更改的自动布局,以便它可以再次运行布局。 (而且,最重要的是,不会陷入布局set-setSize-layout-recursive状态......)
解决方案
我拿出这似乎工作,我究竟是如何希望的解决方案。而不是继承NSTextField
,我只是覆盖layout
在NSTextField
的superview
。在layout
内,我在文本字段上设置preferredMaxLayoutWidth
,然后触发布局传递。这似乎足以让它主要工作,但它留下了令人讨厌的布局问题短暂“错误”。 (见上面的注释)。
解决方案似乎是打电话setNeedsDisplay
,然后一切正常工作。
- (void)layout {
NSTextField *textField = ...;
NSRect oldTextFieldFrame = textField.frame;
[textField setPreferredMaxLayoutWidth:NSWidth(self.bounds) - NSMinX(textField.frame) - 12.0];
[super layout];
NSRect newTextFieldFrame = textField.frame;
if (oldTextFieldFrame.size.height != newTextFieldFrame.size.height) {
[self setNeedsDisplay:YES];
}
}
检查员的宽度是可变的并且是用户控制的。它不受任何约束的控制(也没有定义)。截图中只有灰色视图和NSTextField标签正在使用自动布局。 (所有这些都是在代码中完成的,而不是在Interface Builder中完成的。)我将重新访问子类并在'layout'中手动执行布局,但我希望仅使用约束来缩小Finder的“获取信息”面板中显示的包装行为。 – kennyc
最后,setPreferredMaxLayoutWidth是获得解决方案的关键 – kennyc
“第一次运行时布局宽度”对我来说有窍门。 – dkrdennis