Autoresizing UITextView IOS7

3k views Asked by At

I did a lot of research but none helped with my current situation. What I want to do is have an auto resizing UITextView that grows as the user types. It starts off with a default height and auto grows as the text increases. I added to UITextView to my UIView using the interface builder. now I just need help with making it auto grow. The answers I found said in IOS7 you use [myTextView sizeToFit] which makes it auto-resize but looks like this only works for UITextViews that are added programmatically.

3

There are 3 answers

0
Joseph Chen On

You will need to set a delegate for myTextView and have it respond to changes in its text.

In your view controller's interface declare that it conforms to the UITextViewDelegate protocol, e.g.:

@interface MyViewController : UIViewController <UITextViewDelegate>

In your view controller's -viewDidLoad add this:

self.myTextView.delegate = self;

Then implement the -textViewDidChange: delegate method:

- (void)textViewDidChange:(UITextView *)textView
{
    if (textView != self.myTextView)
        return;

    CGFloat const horizontalPadding = 16.0f; // experiment with these padding values
    CGFloat const verticalPadding = 16.0f;   // until the textview resizes nicely

    CGSize maxSize = CGSizeMake(textView.bounds.size.width - horizontalPadding, CGFLOAT_MAX);
    CGSize textSize;
    if ([textView.text respondsToSelector:@selector(sizeWithAttributes:)]) {
        // iOS7 and above
        NSDictionary *attributes = [NSDictionary dictionaryWithObjectsAndKeys:
                                    [NSValue valueWithCGSize:maxSize], NSViewSizeDocumentAttribute,
                                    textView.font, NSFontAttributeName, nil];
        textSize = [textView.text sizeWithAttributes:attributes];
    } else {
        // iOS6 and below
        textSize = [textView.text sizeWithFont:textView.font
                             constrainedToSize:maxSize
                                 lineBreakMode:NSLineBreakByWordWrapping];
    }

    CGRect newFrame = textView.frame;
    newFrame.size.height = textSize.height + verticalPadding;
    textView.frame = newFrame;
}
0
Schrodingrrr On

I would suggest you try HPGrowingTextView before using a custom solution.

In case you do not like it, you would go about it like this:

  • Create a UITextView with an initial frame and add it to a UIView.
  • Override the textViewDidChange: method and get a CGSize of the content using yourTextView.contentSize property.
  • Use the height property of this CGSize to set the height of your UITextView using CGRectMake.

The contentSize gives you the exact size of the content in your textView, without using sizeWithFont:(deprecated) or sizeWithAttributes:.

But here's the catch: If your textView is contained inside another UIView, you might have to set it's autoresizingMasks to UIViewAutoresizingFlexibleTopMargin, UIViewAutoresizingFlexibleBottomMargin, UIViewAutoresizingFlexibleHeight as per your need, for the succesful resizing of superviews of the textView.

Try going through the code of HPGrowingTextView, and you will understand how this behaviour is implemented.

0
Matej Balantič On

I made a subclass of UITextView just for that:

https://github.com/MatejBalantic/MBAutoGrowingTextView

It is an auto-layout based light-weight UITextView subclass which automatically grows and shrinks based on the size of user input and can be constrained by maximal and minimal height - all without a single line of code.

Made primarily for use in Interface builder and only works with Auto layout.