How do I size a UITextView to its content? How do I size a UITextView to its content? ios ios

How do I size a UITextView to its content?


This works for both iOS 6.1 and iOS 7:

- (void)textViewDidChange:(UITextView *)textView{    CGFloat fixedWidth = textView.frame.size.width;    CGSize newSize = [textView sizeThatFits:CGSizeMake(fixedWidth, MAXFLOAT)];    CGRect newFrame = textView.frame;    newFrame.size = CGSizeMake(fmaxf(newSize.width, fixedWidth), newSize.height);    textView.frame = newFrame;}

Or in Swift (Works with Swift 4.1 in iOS 11)

let fixedWidth = textView.frame.size.widthlet newSize = textView.sizeThatFits(CGSize(width: fixedWidth, height: CGFloat.greatestFiniteMagnitude))textView.frame.size = CGSize(width: max(newSize.width, fixedWidth), height: newSize.height)

If you want support for iOS 6.1 then you should also:

textview.scrollEnabled = NO;


This no longer works on iOS 7 or above

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

This will not work if auto layout is ON. With auto layout, the general approach is to use the sizeThatFits method and update the constant value on a height constraint.

CGSize sizeThatShouldFitTheContent = [_textView sizeThatFits:_textView.frame.size];heightConstraint.constant = sizeThatShouldFitTheContent.height;

heightConstraint is a layout constraint that you typically setup via a IBOutlet by linking the property to the height constraint created in a storyboard.


Just to add to this amazing answer, 2014, if you:

[self.textView sizeToFit];

there is a difference in behaviour with the iPhone6+ only:

enter image description here

With the 6+ only (not the 5s or 6) it does add "one more blank line" to the UITextView. The "RL solution" fixes this perfectly:

CGRect _f = self.mainPostText.frame;_f.size.height = self.mainPostText.contentSize.height;self.mainPostText.frame = _f;

It fixes the "extra line" problem on 6+.


Update

The key thing you need to do is turn off scrolling in your UITextView.

myTextView.scrollEnabled = @NO

Original Answer

To make a dynamically sizing UITextView inside a UITableViewCell, I found the following combination works in Xcode 6 with the iOS 8 SDK:

  • Add a UITextView to a UITableViewCell and constrain it to the sides

  • Set the UITextView's scrollEnabled property to NO. With scrolling enabled, the frame of the UITextView is independent of its content size, but with scrolling disabled, there is a relationship between the two.

  • If your table is using the original default row height of 44 then it will automatically calculate row heights, but if you changed the default row height to something else, you may need to manually switch on auto-calculation of row heights in viewDidLoad:

     tableView.estimatedRowHeight = 150; tableView.rowHeight = UITableViewAutomaticDimension;

For read-only dynamically sizing UITextViews, that’s it. If you’re allowing users to edit the text in your UITextView, you also need to:

  • Implement the textViewDidChange: method of the UITextViewDelegate protocol, and tell the tableView to repaint itself every time the text is edited:

     - (void)textViewDidChange:(UITextView *)textView; {     [tableView beginUpdates];     [tableView endUpdates]; }
  • And don’t forget to set the UITextView delegate somewhere, either in Storyboard or in tableView:cellForRowAtIndexPath: