如何让NSTextField随自动布局中的文本一起增长?

时间:2012-05-05 16:15:10

标签: cocoa nstextfield autolayout

Lion中的自动布局应该让文本字段(以及标签)随着文本的增长而变得相当简单。

文本字段设置为在Interface Builder中包装。

这是一种简单可靠的方法吗?

3 个答案:

答案 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 answerthis answer

更加模糊的是,它依赖于文本字段editable属性的依赖性,如果您在字段上使用绑定并且无法清除Conditionally Sets Editable选项,则autolayout将中断。

答案 2 :(得分:4)

Swift 4

可编辑自动调整NSTextField

基于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_MAXCGFloat.greatestFiniteMagnitude或大数字时的一些错误。当用户选择突出显示字段中的文本时,错误发生在操作期间,它们可以向上和向下拖动滚动到无限远。此外,当用户输入文本时,NSTextField将被消隐,直到用户结束编辑。最后,如果用户选择了NSTextField,然后尝试调整窗口大小,如果self.frame.size.height的值太大,窗口将会挂起。