How to make NSTextView grow with text?

I am creating a simple word processor where a user can add a text field to an NSView , similar to the function in Pages. The problem is that when you add it, it will remain the same size, regardless of how much text the user enters. I want it to increase when the user enters text, I tried this GitHub project, but when I use it, the text field expands only when I have deleted all the text, as if the code did not respond before the textDidEndEditing method. After working a bit with NSTextView , I found that it would be more suitable for the task, but I still can not get it to work. I am running Mavericks and Xcode 5.0.1.

Hope someone can help me!

+1
source share
2 answers

This example fixed this for me: https://developer.apple.com/library/mac/documentation/cocoa/conceptual/TextUILayer/Tasks/TextInScrollView.html

You must put it in an NSScrollView. The behavior is not the same as in a UITextView (if you have an iOS background).

0
source

The next section uses the NSTextView subclass, which must be created in code. For reasons of its own, Xcode will not be allowed to instantiate an NSTextView at the tip without an enclosing NSScrollView instance.

This class allows you to determine only the internal height of the text - the width remains undefined, which allows you to increase the view with its closing view. I used this in NSStackView and it seems to work well. Trying to trick NSTextField so that it could wrap multi-line text, edit and maintain automatic layout was too messy.

Please note that we support the focus ring as I wanted my class to work as an Uber text box. Also note that we do not support the border. In my actual use, I create a composite view that wraps a custom text view. This kind of shell draws a border as needed.

 @interface BPTextViewField : NSTextView // primitives @property (assign, nonatomic) CGFloat borderOffsetX; @property (assign, nonatomic) CGFloat borderOffsetY; @end @implementation BPTextViewField #pragma mark - #pragma mark Life cycle - (instancetype)initWithFrame:(NSRect)frameRect textContainer:(nullable NSTextContainer *)container { self = [super initWithFrame:frameRect textContainer:container]; if (self) { [self commonInit]; } return self; } - (nullable instancetype)initWithCoder:(NSCoder *)coder { self = [super initWithCoder:coder]; if (self) { [self commonInit]; } return self; } - (void)commonInit { _borderOffsetX = 1; _borderOffsetY = 3; self.usesFontPanel = NO; self.usesFindPanel = NO; } #pragma mark - #pragma mark Auto layout - (NSSize)intrinsicContentSize { NSTextContainer* textContainer = [self textContainer]; NSLayoutManager* layoutManager = [self layoutManager]; [layoutManager ensureLayoutForTextContainer: textContainer]; NSSize size = [layoutManager usedRectForTextContainer: textContainer].size; return NSMakeSize(NSViewNoIntrinsicMetric, size.height); } #pragma mark - #pragma mark Accessors - (void)setString:(NSString *)string { [super setString:string]; [self invalidateIntrinsicContentSize]; } #pragma mark - #pragma mark Text change notifications - (void)didChangeText { [super didChangeText]; [self invalidateIntrinsicContentSize]; } #pragma mark - #pragma mark Drawing - (void)drawRect:(NSRect)rect { [super drawRect:rect]; } #pragma mark - #pragma mark Focus ring - (void)drawFocusRingMask { if (self.editable) { NSRectFill(self.focusRingMaskBounds); } } - (NSRect)focusRingMaskBounds { NSRect r = [self bounds]; return NSMakeRect(r.origin.x - self.borderOffsetX, r.origin.y - self.borderOffsetY, r.size.width + self.borderOffsetX * 2, r.size.height + self.borderOffsetY * 2); } @end 
+2
source

Source: https://habr.com/ru/post/895795/


All Articles