NSTextView无法使用自动布局正确调整大小

时间:2022-11-04 09:53:31

I have a simple layout, which consists of NSView and its subview NSTextView. NSTextView is programmatically filled with some text that spawns multiple lines. I tie everything together using auto-layout (all done programmatically). However, when everything is displayed NSTextView is cut off, only one line is showing.

我有一个简单的布局,它由NSView及其子视图NSTextView组成。 NSTextView以编程方式填充了一些产生多行的文本。我使用自动布局(所有以编程方式完成)将所有内容绑定在一起。但是,当显示所有内容时,NSTextView将被切断,只显示一行。

After searching the web, the best answer I could find was:

搜索网络后,我能找到的最佳答案是:

Using Autolayout with expanding NSTextViews

使用Autolayout扩展NSTextViews

However, this only works if I manually change the text in NSTextView after everything is displayed (which is not really my use case). The views are readjusted and the whole NSTextView is displayed.

但是,这只有在我显示所有内容后手动更改NSTextView中的文本时才有效(这不是我的用例)。视图重新调整,并显示整个NSTextView。

I am trying to figure out when NSViewController is done with laying out subviews so that I could call invalidateIntrinsicContentSize on the NSTextView. The equivalent of viewDidLayoutSubviews in UIViewController.

我试图找出NSViewController何时完成布局子视图,以便我可以在NSTextView上调用invalidateIntrinsicContentSize。相当于UIViewController中的viewDidLayoutSubviews。

Nothing I tried worked so far. I attempted calling invalidateIntrinsicContentSize for NSTextView:

到目前为止我没有尝试过任何工作。我试图为NSTextView调用invalidateIntrinsicContentSize:

  • At the end of loadView
  • 在loadView结束时
  • After I filled NSTextView with my text
  • 在我用我的文本填充NSTextView之后

Is there a better way to achieve this?

有没有更好的方法来实现这一目标?

1 个解决方案

#1


6  

After further research, found the answer:

经过进一步研究,找到了答案:

  1. Create custom NSView subclass that contains NSTextView
  2. 创建包含NSTextView的自定义NSView子类
  3. In NSView subclass override layout method that calls invalidateIntrinsicContentSize
  4. 在NSView子类中,覆盖调用invalidateIntrinsicContentSize的布局方法

Also check out this link that explains subtleties of auto layout and intrinsic content size (among many other things):

另请查看此链接,该链接解释了自动布局和内在内容大小的细微差别(以及许多其他内容):

http://www.objc.io/issue-3/advanced-auto-layout-toolbox.html

http://www.objc.io/issue-3/advanced-auto-layout-toolbox.html

Sample code:

示例代码:

@interface MyView : NSView
  @property MyTextView *textView;
@end

@implementation MyView

// init & create content & set constraints

-(void) layout {
    [super layout];
    [self.textView invalidateIntrinsicContentSize];
}

@end

Implementation of MyTextView:

MyTextView的实现:

@implementation MyTextView

- (NSSize) intrinsicContentSize {
    NSTextContainer* textContainer = [self textContainer];
    NSLayoutManager* layoutManager = [self layoutManager];
    [layoutManager ensureLayoutForTextContainer: textContainer];
    return [layoutManager usedRectForTextContainer: textContainer].size;
}

- (void) didChangeText {
    [super didChangeText];
    [self invalidateIntrinsicContentSize];
}

@end

#1


6  

After further research, found the answer:

经过进一步研究,找到了答案:

  1. Create custom NSView subclass that contains NSTextView
  2. 创建包含NSTextView的自定义NSView子类
  3. In NSView subclass override layout method that calls invalidateIntrinsicContentSize
  4. 在NSView子类中,覆盖调用invalidateIntrinsicContentSize的布局方法

Also check out this link that explains subtleties of auto layout and intrinsic content size (among many other things):

另请查看此链接,该链接解释了自动布局和内在内容大小的细微差别(以及许多其他内容):

http://www.objc.io/issue-3/advanced-auto-layout-toolbox.html

http://www.objc.io/issue-3/advanced-auto-layout-toolbox.html

Sample code:

示例代码:

@interface MyView : NSView
  @property MyTextView *textView;
@end

@implementation MyView

// init & create content & set constraints

-(void) layout {
    [super layout];
    [self.textView invalidateIntrinsicContentSize];
}

@end

Implementation of MyTextView:

MyTextView的实现:

@implementation MyTextView

- (NSSize) intrinsicContentSize {
    NSTextContainer* textContainer = [self textContainer];
    NSLayoutManager* layoutManager = [self layoutManager];
    [layoutManager ensureLayoutForTextContainer: textContainer];
    return [layoutManager usedRectForTextContainer: textContainer].size;
}

- (void) didChangeText {
    [super didChangeText];
    [self invalidateIntrinsicContentSize];
}

@end