一旦用户输入足够的文本以溢出控件的宽度(如要求的 on this post ),我试图让我的 NSTextField 的高度增长(就像在 iChat 或 Adium 中一样)
我已经采纳了已接受的答案,但我似乎无法让它发挥作用。我已将我的尝试上传到 http://scottyob.com/pub/autoGrowingExample.zip
理想情况下,当文本增长时,包含的窗口应该随之增长,但我在这里尝试了一些小步骤。
最佳答案
阅读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/