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

标签 macos cocoa nstextfield autolayout

一旦用户输入足够的文本以溢出控件的宽度(如要求的 on this post ),我试图让我的 NSTextField 的高度增长(就像在 iChat 或 Adium 中一样)

我已经采纳了已接受的答案,但我似乎无法让它发挥作用。我已将我的尝试上传到 http://scottyob.com/pub/autoGrowingExample.zip

理想情况下,当文本增长时,包含的窗口应该随之增长,但我在这里尝试了一些小步骤。

最佳答案

解决了! (灵感来自https://github.com/jerrykrinock/CategoriesObjC/blob/master/NS(Attributed)String%2BGeometrics/NS(Attributed)String%2BGeometrics.m)

阅读Apple Documentation通常是有帮助的。 Apple 设计了所有这些文本布局内容,使其强大到足以处理各种 complicated edge cases这有时非常有帮助,有时却没有。

首先,我将文本字段设置为在分词时换行,因此我们实际上得到了多行。 (您的示例代码甚至有一个 if 语句,因此当关闭包装时它什么也不做)。

这个的技巧是要注意,当编辑文本时,它是由“字段编辑器”打印的 - 一个重量级 NSTextView 对象,由 NSWindow 拥有>,由当前“第一响应者”(选定)的任何 NSTextField 重用。 NSTextView 有一个 NSTextContainer (文本所在的矩形),它有一个 NSLayoutManager 来布局文本。我们可以询问布局管理器想要使用多少空间,以获得文本字段的新高度。

另一个技巧是重写 NSText 委托(delegate)方法 - (void)textDidChange:(NSNotification *)notification ,以便在文本更改时使内在内容大小无效(因此,当您通过按回车键提交更改时,它不会只是等待更新)。

我没有按照您最初的建议使用 cellSizeForBounds 的原因是我无法解决您的问题 - 即使使单元格的固有内容大小无效,cellSizeForBounds: 继续返回旧尺寸。

GitHub 上查找示例项目.

@interface TSTTextGrowth()
{
    BOOL _hasLastIntrinsicSize;
    BOOL _isEditing;
    NSSize _lastIntrinsicSize;
}

@end

@implementation TSTTextGrowth

- (void)textDidBeginEditing:(NSNotification *)notification
{
    [super textDidBeginEditing:notification];
    _isEditing = YES;
}

- (void)textDidEndEditing:(NSNotification *)notification
{
    [super textDidEndEditing:notification];
    _isEditing = NO;
}

- (void)textDidChange:(NSNotification *)notification
{
    [super textDidChange:notification];
    [self invalidateIntrinsicContentSize];
}

-(NSSize)intrinsicContentSize
{
    NSSize intrinsicSize = _lastIntrinsicSize;

    // Only update the size if we’re editing the text, or if we’ve not set it yet
    // If we try and update it while another text field is selected, it may shrink back down to only the size of one line (for some reason?)
    if(_isEditing || !_hasLastIntrinsicSize)
    {
        intrinsicSize = [super intrinsicContentSize];

        // If we’re being edited, get the shared NSTextView field editor, so we can get more info
        NSText *fieldEditor = [self.window fieldEditor:NO forObject:self];
        if([fieldEditor isKindOfClass:[NSTextView class]])
        {
            NSTextView *textView = (NSTextView *)fieldEditor;
            NSRect usedRect = [textView.textContainer.layoutManager usedRectForTextContainer:textView.textContainer];

            usedRect.size.height += 5.0; // magic number! (the field editor TextView is offset within the NSTextField. It’s easy to get the space above (it’s origin), but it’s difficult to get the default spacing for the bottom, as we may be changing the height

            intrinsicSize.height = usedRect.size.height;
        }

        _lastIntrinsicSize = intrinsicSize;
        _hasLastIntrinsicSize = YES;
    }

    return intrinsicSize;
}

@end

最后一点,我自己从未真正使用过自动布局 - 演示看起来很棒,但每当我自己实际尝试时,我都无法让它正常工作,这让事情变得更加复杂。然而,在这种情况下,我认为它实际上确实节省了很多工作 - 没有它, -intrinsicContentSize 将不存在,并且您可能必须自己设置框架,计算新的原点以及新的大小(不是太难,只是更多的代码)。

关于macos - 让 NSTextField 随自动布局中的文本一起增长?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14107385/

相关文章:

cocoa - 没有数组的 NSArrayController

cocoa - NSTextField 中的文本格式

objective-c - 带有 NSTextField 的 NSPopover 在打开时显示具有不透明背景的文本字段,然后在弹出动画后变为透明

swift - 在 NSTableView 中编辑 NSTextField 时按下 Enter 时选择下一行

javascript - 这种 Safari 行为是否违反了 ECMAScript 规范?

MacOS:手动强制启动守护进程

c - 为什么我在 Ubuntu 上遇到段错误,但在 Mac 上却没有?

ruby - 需要帮助在 Mac OSX 10.7 上安装 Ruby 1.9.2

objective-c - 选中抑制按钮时禁用 NSAlert 按钮

iphone - 更改按钮的外观 - iPhone