How to resize NSTextView according to its content?

前端 未结 4 2202
南方客
南方客 2020-12-14 09:11

I am trying to set an attributed string within NSTextView. I want to increase its height based on its content, initially it is set to some default value.

So I tried

相关标签:
4条回答
  • 2020-12-14 09:28

    Based on @Peter Hosey's answer, here is an extension to NSTextView in Swift 4.2:

    extension NSTextView {
    
        var contentSize: CGSize {
            get {
                guard let layoutManager = layoutManager, let textContainer = textContainer else {
                    print("textView no layoutManager or textContainer")
                    return .zero
                }
    
                layoutManager.ensureLayout(for: textContainer)
                return layoutManager.usedRect(for: textContainer).size
            }
        }
    }
    
    0 讨论(0)
  • 2020-12-14 09:31
    NSTextView *textView = [[NSTextView alloc] init];
    textView.font = [NSFont systemFontOfSize:[NSFont systemFontSize]];
    textView.string = @"Lorem ipsum";
    
    [textView.layoutManager ensureLayoutForTextContainer:textView.textContainer];
    
    textView.frame = [textView.layoutManager usedRectForTextContainer:textView.textContainer];
    
    0 讨论(0)
  • 2020-12-14 09:34
    + (float)heightForString:(NSString *)myString font:(NSFont *)myFont andWidth:(float)myWidth andPadding:(float)padding {
         NSTextStorage *textStorage = [[NSTextStorage alloc] initWithString:myString];
         NSTextContainer *textContainer = [[NSTextContainer alloc] initWithContainerSize:NSMakeSize(myWidth, FLT_MAX)];
         NSLayoutManager *layoutManager = [[NSLayoutManager alloc] init];
         [layoutManager addTextContainer:textContainer];
         [textStorage addLayoutManager:layoutManager];
         [textStorage addAttribute:NSFontAttributeName value:myFont
                        range:NSMakeRange(0, textStorage.length)];
         textContainer.lineFragmentPadding = padding;
    
         (void) [layoutManager glyphRangeForTextContainer:textContainer];
         return [layoutManager usedRectForTextContainer:textContainer].size.height;
    }
    

    I did the function using this reference: Documentation

    Example:

    float width = textView.frame.size.width - 2 * textView.textContainerInset.width;
    float proposedHeight = [Utils heightForString:textView.string font:textView.font andWidth:width
                                       andPadding:textView.textContainer.lineFragmentPadding];
    
    0 讨论(0)
  • 2020-12-14 09:37

    Ask the text view for its layout manager and its text container. Then, force the layout manager to perform layout, and then ask the layout manager for the used rectangle for the text container.

    See also the Text System Overview.

    0 讨论(0)
提交回复
热议问题