得到一个用的NSTextField汽车布局中的文字发展壮大? [英] getting a NSTextField to grow with the text in auto layout?

查看:134
本文介绍了得到一个用的NSTextField汽车布局中的文字发展壮大?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图让我的NSTextField有其高度增长(就像在iChat或Adium的),一旦用户输入足够的文本溢出控件的宽度(如问<一个href=\"http://stackoverflow.com/questions/10463680/how-to-let-nstextfield-grow-with-the-text-in-auto-layout\">on这个帖子)

I'm trying to get my NSTextField to have its height grow (much like in iChat or Adium) once the user types enough text to overflow the width of the control (as asked on this post)

我的形式实现接受的答案但我似乎无法得到它的工作。我已上载我尝试在<一个href=\"http://scottyob.com/pub/autoGrowingExample.zip\">http://scottyob.com/pub/autoGrowingExample.zip

I've implimented the accepted answer yet I can't seem to get it to work. I have uploaded my attempt at http://scottyob.com/pub/autoGrowingExample.zip

在理想情况下,当文本的增长,包含窗口应与它成长,但我在这里想小步。

Ideally, when the text grows, the containing window should grow with it, but I'm trying baby steps here.

推荐答案

解决它! (由<一个启发href=\"https://github.com/jerrykrinock/CategoriesObjC/blob/master/NS(Attributed)String%2BGeometrics/NS(Attributed)String%2BGeometrics.m\">https://github.com/jerrykrinock/CategoriesObjC/blob/master/NS(Attributed)String%2BGeometrics/NS(Attributed)String%2BGeometrics.m )

读<一个href=\"https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/TextLayout/TextLayout.html#//apple_ref/doc/uid/10000158-SW1\">Apple文档通常是有帮助的。苹果设计这一切的文本布局东西足够强大,可以处理各种<一个href=\"https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/TextStorageLayer/Tasks/Region.html#//apple_ref/doc/uid/20000925-CJBBIAAF\">complicated边缘情况这有时是非常有用的,有时不是。

Reading the Apple Documentation is usually helpful. Apple has engineered all this text layout stuff to be powerful enough to handle all sorts of complicated edge cases which is sometimes extremely helpful, and sometimes not.

首先,我将文本字段设置为换行字断裂线,所以我们实际上得到多行。 (你的榜样code甚至有一个if语句所以什么也没做,当包装被关闭的话)。

Firstly, I set the text field to wrap lines on word break, so we actually get multiple lines. (Your example code even had an if statement so it did nothing at all when wrapping was turned off).

诀窍这个是要注意的是文本正在编辑的时候,它是由一个'字段编辑器印 - 一个沉重的重量 NSTextView 对象,由一个拥有 NSWindow ,这是由什么的NSTextField 是目前的第一反应者(选择)重用。在 NSTextView 有一个 NSTextContainer (矩形,其中文本行),其中有一个 NSLayoutManager 来布局的文本。我们可以问它想要多少空间使用了布局管理器,让我们的文本字段的新高度。

The trick to this one was to note that when text is being edited, it’s printed by a ‘field editor’ – a heavy weight NSTextView object, owned by an NSWindow, that’s reused by whatever NSTextField is currently the ‘first responder’ (selected). The NSTextView has a single NSTextContainer (rectangle where text goes), which has a NSLayoutManager to layout the text. We can ask the layout manager how much space it wants to use up, to get the new height of our text field.

另一个诀窍是覆盖 NSText 委托方法 - (无效)textDidChange:(NSNotification *)通知当文字被改变(所以它不只是等待更新,当您提交由pressing回报更改)无效的内在含量的大小。

The other trick was to override the NSText delegate method - (void)textDidChange:(NSNotification *)notification to invalidate the intrinsic content size when the text is changed (so it doesn’t just wait to update when you commit changed by pressing return).

我没有使用的原因 cellSizeForBounds 为您最初建议是我没能解决你的问题 - 无效细胞的内在内容的大小,即使 cellSizeForBounds:继续返回旧的大小

The reason I didn’t use cellSizeForBounds as you originally suggested was I couldn’t solve your problem – even when invalidating the intrinsic content size of the cell, cellSizeForBounds: continued to return the old size.

查找 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 将不存在,而且你可能必须设置框架自己,计算新的原点,以及新的大小(不太难,只是更code)。

As a last note, I’ve never actually used auto layout myself – the demos look amazing, but whenever I actually try it myself, I can’t get it to work quite right and it makes things more complicated. However, in this case, I think it actually did save a bunch of work – without it, -intrinsicContentSize wouldn’t exist, and you’d possibly have to set the frame yourself, calculating the new origin as well as the new size (not too difficult, but just more code).

这篇关于得到一个用的NSTextField汽车布局中的文字发展壮大?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆