Lion中的自动布局应该让文本字段(以及标签)随着文本的增长而变得相当简单。
文本字段设置为在Interface Builder中包装。
这是一种简单可靠的方法吗?
答案 0 :(得分:46)
intrinsicContentSize
中的方法NSView
会返回视图本身认为的内在内容大小。
NSTextField
在不考虑其单元格的wraps
属性的情况下计算此值,因此如果将其放在一行中,它将报告文本的尺寸。
因此,NSTextField
的自定义子类可以覆盖此方法以返回更好的值,例如单元格的cellSizeForBounds:
方法提供的值:
-(NSSize)intrinsicContentSize
{
if ( ![self.cell wraps] ) {
return [super intrinsicContentSize];
}
NSRect frame = [self frame];
CGFloat width = frame.size.width;
// Make the frame very high, while keeping the width
frame.size.height = CGFLOAT_MAX;
// Calculate new height within the frame
// with practically infinite height.
CGFloat height = [self.cell cellSizeForBounds: frame].height;
return NSMakeSize(width, height);
}
// you need to invalidate the layout on text change, else it wouldn't grow by changing the text
- (void)textDidChange:(NSNotification *)notification
{
[super textDidChange:notification];
[self invalidateIntrinsicContentSize];
}
答案 1 :(得分:4)
接受的答案是基于操纵intrinsicContentSize
,但在所有情况下可能都没有必要。如果(a)您将文本字段设为preferredMaxLayoutWidth
并且(b)使字段不是editable
,则Autolayout将增大和缩小文本字段的高度。这些步骤使文本字段能够确定其固有宽度并计算自动布局所需的高度。有关详细信息,请参阅this answer和this answer。
更加模糊的是,它依赖于文本字段editable
属性的依赖性,如果您在字段上使用绑定并且无法清除Conditionally Sets Editable
选项,则autolayout将中断。
答案 2 :(得分:4)
基于Peter Lapisu的Objective-C帖子
子类NSTextField
,添加以下代码。
override var intrinsicContentSize: NSSize {
// Guard the cell exists and wraps
guard let cell = self.cell, cell.wraps else {return super.intrinsicContentSize}
// Use intrinsic width to jive with autolayout
let width = super.intrinsicContentSize.width
// Set the frame height to a reasonable number
self.frame.size.height = 750.0
// Calcuate height
let height = cell.cellSize(forBounds: self.frame).height
return NSMakeSize(width, height);
}
override func textDidChange(_ notification: Notification) {
super.textDidChange(notification)
super.invalidateIntrinsicContentSize()
}
将self.frame.size.height
设置为“合理的数字”可以避免使用FLT_MAX
,CGFloat.greatestFiniteMagnitude
或大数字时的一些错误。当用户选择突出显示字段中的文本时,错误发生在操作期间,它们可以向上和向下拖动滚动到无限远。此外,当用户输入文本时,NSTextField
将被消隐,直到用户结束编辑。最后,如果用户选择了NSTextField
,然后尝试调整窗口大小,如果self.frame.size.height
的值太大,窗口将会挂起。