Kaelin Colclasure Kaelin Colclasure - 1 month ago 8
Objective-C Question

How do I make a Cocoa NSTextView grow as the user types into it?

For a Cocoa application I am writing, I would like to support a panel to the right of the main document content where users can add notes for the currently selected document content. (If you are familiar with Microsoft Word or Scrivener, this feature is similar to the comment feature in those applications.) Scrivener does a nice job of starting with a text field sized to fit the default text, and then growing it taller as the user types into it. I'd like to implement the same behavior for my Cocoa app.

What's the basic strategy?

Answer

There are delegate methods that allow you to capture the actual keystrokes as they come in.

Implement the below delegate method to resign first responder, based upon the keyboard

-(BOOL)textFieldShouldReturn:(UITextField *)textfield

Implement the below delegate method to detect when focus has been given back to the TextField. You may also want to perform the deletion of current text, or retain the text that was already there if you wish

-(void)textFieldDidBeginEditing:(UITextField *)textfield

Implement the below delegate method to detect the character(s) entered and where (based on the caret position), and essentially add the characters to your privately held and displayed string (displayed out to your textfield that is)

-(BOOL)textView:(NSTextView *)aTextView shouldChangeTextInRange:(NSRange)affectedCharRange replacementString:(NSString *)replacementString

Implement the below delegate method to detect when editing has finished so that you can perform any other cleanup etc... that you wish to do.

-(void)textFieldDidEndEditing:(UITextField *)textField

I will get back to you on the dynamic sizing of your TextView itself, but that (at least on iOS) as Ive seen has a solution and at one point I have used it. You will essentially make your font size static, potentially your width static, then edit your height based on how many lines you have, or you could keep your height static, and change your width based on characters, etc... up to you.

Here is a great set of responses on StackOverflow about dynamic sizing How do I size a UITextView to its content?

So if you combine the keystroke recognition with the dynamic sizing you should have it!!!