views:

14992

answers:

6

Is there a good way to adjust the size of a UITextView to conform to it's content? Say for instance I have a UITextView that contains one line of text:

"Hello world"

I then add another line of text:

"Goodbye world"

Is there a good way in Cocoa Touch to get the rect that will hold all of the lines in the text view so that I can adjust the parent view accordingly?

As another example, look at the Notes field for events in the Calendar application--note how the cell (and the UITextView it contains) expands to hold all lines of text in the notes string.

+2  A: 

Did you try [textView sizeThatFits:textView.bounds] ?

Edit: sizeThatFits returns the size but does not actually resize the component. I'm not sure if that's what you want, or if [textView sizeToFit] is more what you were looking for. In either case, I do not know if it will perfectly fit the content like you want, but it's the first thing to try.

Mike McMaster
+2  A: 

Another method is the find the size a particular string will take up using the NSString method:

-(CGSize)sizeWithFont:(UIFont *)font constrainedToSize:(CGSize)size

This returns the size of the rectangle that fits the given string with the given font. Pass in a size with the desired width and a maximum height, and then you can look at the height returned to fit the text. There is a version that lets you specify line break mode also.

You can then use the returned size to change the size of your view to fit.

Code Addict
+2  A: 

Combined with Mike McMaster's answer, you might want to do something like:

[myTextView setDelegate: self];

...

- (void)textViewDidChange:(UITextView *)textView {
  if (myTextView == textView) {
     // it changed.  Do resizing here.
  }
}
Olie
+9  A: 

In my (limited) experience,

- (CGSize)sizeWithFont:(UIFont *)font forWidth:(CGFloat)width lineBreakMode:(UILineBreakMode)lineBreakMode

does not respect newline characters, so you can end up with a lot shorter CGSize than is actually required.

- (CGSize)sizeWithFont:(UIFont *)font constrainedToSize:(CGSize)size

does seem to respect the newlines.

Also, the text isn't actually rendered at the top of the UITextView. In my code, I set the new height of the UITextView to be 24 pixels larger than the height returned by the sizeOfFont methods.

That gets the size as if it would draw the text on a UILabel. If you set that size to the uitextview's frame then you will still have some scrolling necessary in it.
Kevlar
+1  A: 

Hope this helps:

- (void)textViewDidChange:(UITextView *)textView {
  CGSize textSize = textview.contentSize;
  if (textSize != textView.frame.size)
      textView.frame.size = textSize;
}
Dr. Marty
This doesn't work! It causes an error: "lvalue required as left operand of assignment"
Colins
@Colins, I don't know about this answer, but: the error means that you can't just assign the size of the from on the textView. You have to do `CGRect frame = textView.frame; frame.size = textSize; textView.frame = frame;` That said, this answer is most likely wrong anyway :)
Yar
+15  A: 

There is actually a very easy way to do resizing of the UITextView to its correct height of the content. It can be done using the UITextView contentSize.

CGRect frame = _textView.frame;
frame.size.height = _textView.contentSize.height;
_textView.frame = frame;

One thing to note is that the correct contentSize is only available after the UITextView has been added to the view with addSubview. Prior to that it is equal to frame.size

Ronnie Liew