183

I have a view that is laid out completely using auto layout programmatically. I have a UITextView in the middle of the view with items above and below it. Everything works fine, but I want to be able to expand UITextView as text is added. This should push everything below it down as it expands.

I know how to do this the "springs and struts" way, but is there an auto layout way of doing this? The only way I can think of is by removing and re-adding the constraint every time it needs to grow.

tharris
  • 2,192
  • 2
  • 13
  • 14
  • 5
    You can make an IBOutlet to a height constraint for the text view, and just modify the constant when you want it to grow, no need to remove and add. – rdelmar Jun 01 '13 at 01:22
  • 4
    2017, a huge tip that often holds you up: ***IT ONLY WORKS IF YOU SET IT AFTER VIEWDID >APPEAR<*** it's very frustrating if you set the text say at ViewDidLoad - it won't work! – Fattie May 17 '17 at 01:34
  • 2
    tip No2: if you call [someView.superView layoutIfNeeded] THEN it might work in viewWillAppear() ;) – Yaro Aug 03 '17 at 06:45

17 Answers17

584

Summary: Disable scrolling of your text view, and don't constraint its height.

To do this programmatically, put the following code in viewDidLoad:

let textView = UITextView(frame: .zero, textContainer: nil)
textView.backgroundColor = .yellow // visual debugging
textView.isScrollEnabled = false   // causes expanding height
view.addSubview(textView)

// Auto Layout
textView.translatesAutoresizingMaskIntoConstraints = false
let safeArea = view.safeAreaLayoutGuide
NSLayoutConstraint.activate([
    textView.topAnchor.constraint(equalTo: safeArea.topAnchor),
    textView.leadingAnchor.constraint(equalTo: safeArea.leadingAnchor),
    textView.trailingAnchor.constraint(equalTo: safeArea.trailingAnchor)
])

To do this in Interface Builder, select the text view, uncheck Scrolling Enabled in the Attributes Inspector, and add the constraints manually.

Note: If you have other view/s above/below your text view, consider using a UIStackView to arrange them all.

ma11hew28
  • 121,420
  • 116
  • 450
  • 651
vitaminwater
  • 6,934
  • 3
  • 19
  • 23
  • 12
    Works for me (iOS 7 @ xcode 5). The caveat is that simply unchecking "scrolling enabled" in IB won't help. You have to programmatically do it. – Kenneth Jiang Sep 08 '14 at 22:37
  • Has anyone else noticed that this only works up until a certain font size? For instance I'm displaying maybe 2000 words of text with `scrollEnabled = false`. When my font size is 19, everything displays fine, and the textView resizes ok. When I set my font size to 20, nothing is displayed at all. Setting `scrollEnabled = true` allows much larger font sizes to be displayed without issue. – Michael J Petrie Feb 22 '16 at 03:25
  • In addition to my above comment - when the text disappears (size 20 and above), it's still "there" in the textView, it's just not visible at all. I can select it, copy & paste into another application and view it just fine. It's just that it won't display. Would appreciate any possible solutions. – Michael J Petrie Feb 22 '16 at 03:35
  • Ok, for anyone interested, I found the reason for my text disappearing [here](http://stackoverflow.com/questions/23582497/uitextview-text-becomes-invisible-after-height-reaches-8192-0?lq=1). UITextView cannot exceed a height of 8192. – Michael J Petrie Feb 22 '16 at 04:36
  • 14
    How do I set a max height on the text view and then get the text view to scroll after its content has surpassed the height of the text view? – ma11hew28 Dec 14 '16 at 21:46
  • Not sure if I understand, but maybe by embedding it inside a UIScrollView ? – vitaminwater Dec 16 '16 at 10:11
  • Working only if text has some length. Not working for me if I set textview text to nil. It should resize to 0 height but it's not happening. Did i miss something ? – Pankaj Yadav Jan 07 '17 at 09:59
  • @iOSGeek do you really need to try to display a nil string ? – vitaminwater Mar 06 '17 at 18:32
  • @vitaminwater yes! sometimes getting nil string from web service. – Pankaj Yadav Mar 09 '17 at 14:03
  • 3
    @iOSGeek just create a UITextView subclass and overwrite `intrinsicContentSize` like this `- (CGSize)intrinsicContentSize { CGSize size = [super intrinsicContentSize]; if (self.text.length == 0) { size.height = UIViewNoIntrinsicMetric; } return size; }`. Tell me if it's working for you. Didn't test it myself. – manuelwaldner Mar 14 '17 at 08:27
  • 2
    Set this property and put UITextView in UIStackView. Voilla - self resizing textView!) – Nike Kov Aug 14 '17 at 16:26
  • 3
    This answer is gold. With Xcode 9 it also works if you disable the checkbox in IB. – bio Dec 19 '17 at 16:58
  • As to **why** this answer works. I've wrote the following answer [here](https://stackoverflow.com/a/52337167/5175709) – mfaani Sep 14 '18 at 18:07
61

Here's a solution for people who prefer to do it all by auto layout:

In Size Inspector:

  1. Set content compression resistance priority vertical to 1000.

  2. Lower the priority of constraint height by click "Edit" in Constraints. Just make it less than 1000.

enter image description here

In Attributes Inspector:

  1. Uncheck "Scrolling Enabled"
Michael Revlis
  • 1,463
  • 11
  • 14
  • 1
    This is working perfectly. I did not set the height. Increasing the priority of UItextview's vertical compression resistance to 1000 was only required. The UItextView has some insets, that's why autolayout gives errors as UItextview will need atleast 32 height, even if no content is in it, when scrolling is disabled. – nr5 Sep 02 '17 at 08:02
  • Update: Height constraint is required if you want the height to be minimum to 20 or anything else. Other wise 32 will be considered as the min height. – nr5 Sep 02 '17 at 08:16
  • @Nil Glad to hear it helps. – Michael Revlis Sep 04 '17 at 06:50
  • @MichaelRevlis, This works great. but when there is a large text then text is not displaying. you can select text do other processing but it is not visible. can you please help me with that. ? it happens when I uncheck scrolling enabled option. when I make textview scrolling enable then it displays perfectly but i want text view not to scroll. – Bhautik Ziniya Nov 08 '17 at 12:57
  • @BhautikZiniya, have you try to build your app on a real device? I think it might be a simulator displaying bug. I have an UITextView with text font size 100. It is displayed fine on a real device but texts are invisible on a simulator. – Michael Revlis Nov 09 '17 at 09:15
  • If I could award you 10 points for taking the time to share this solution I would. Thank you. – forrest Oct 24 '19 at 21:57
  • @fmz Yes you did. Thank you. =D – Michael Revlis Oct 25 '19 at 11:13
38

UITextView doesn't provide an intrinsicContentSize, so you need to subclass it and provide one. To make it grow automatically, invalidate the intrinsicContentSize in layoutSubviews. If you use anything other than the default contentInset (which I do not recommend), you may need to adjust the intrinsicContentSize calculation.

@interface AutoTextView : UITextView

@end

#import "AutoTextView.h"

@implementation AutoTextView

- (void) layoutSubviews
{
    [super layoutSubviews];

    if (!CGSizeEqualToSize(self.bounds.size, [self intrinsicContentSize])) {
        [self invalidateIntrinsicContentSize];
    }
}

- (CGSize)intrinsicContentSize
{
    CGSize intrinsicContentSize = self.contentSize;

    // iOS 7.0+
    if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0f) {
        intrinsicContentSize.width += (self.textContainerInset.left + self.textContainerInset.right ) / 2.0f;
        intrinsicContentSize.height += (self.textContainerInset.top + self.textContainerInset.bottom) / 2.0f;
    }

    return intrinsicContentSize;
}

@end
dhallman
  • 661
  • 6
  • 7
  • 1
    This worked well for me. In addition, I would set 'scrollEnabled' to NO in Interface Builder for this Text View, since it already shows all its contents without scrolling needed. More importantly, if it sits inside an actual scroll view, you can experience cursor jumping near the bottom of the text view, if you do not disable scrolling on the text view itself. – idStar Oct 12 '13 at 15:30
  • This works nicely. Interestingly when overriding `setScrollEnabled:` to always set it to `NO` you'll get an infinite loop for an ever-growing intrinsic content size. – Pascal Dec 22 '13 at 18:47
  • On iOS 7.0, I also needed to call `[textView sizeToFit]` in the `textViewDidChange:` delegate callback for Auto Layout to grow or shrink the textview (and recalculate any dependent constraints) after each keystroke. – followben Jan 28 '14 at 05:11
  • 6
    This appears to no longer be necessary in **iOS 7.1** To fix and provide backwards compatibility, wrap the condition in `-(void)layoutSubviews` and wrap _all_ the code in `-(CGSize)intrinsicContentSize` with `version >= 7.0f && version < 7.1f` + `else return [super intrinsicContentSize];` – David James Mar 18 '14 at 11:41
  • Pitfall: if your TextView has constraints with the relationship "greater or equal" that connect it to an outer view, the reported contentSize is wrong. Solution: Only use "equal" constraints. – patric.schenke Apr 28 '14 at 13:35
  • 1
    @DavidJames this is still necessary in ios 7.1.2, i don't know where you are testing. – Softlion Oct 06 '14 at 06:31
  • Perfect !! Exactly what I was looking for without having to disable scrolling. – user1046037 Aug 10 '18 at 00:50
  • @patric.schenke IMHO I think you might be using the wrong relationship. Try less than or equal. I made the same mistake. The coordinate system starts from top left – user1046037 Aug 10 '18 at 01:03
32

The view containing UITextView will be assigned its size with setBounds by AutoLayout. So, this is what I did. The superview is initially set up all the other constraints as they should be, and in the end I put one special constraint for UITextView's height, and I saved it in an instance variable.

_descriptionHeightConstraint = [NSLayoutConstraint constraintWithItem:_descriptionTextView
                                 attribute:NSLayoutAttributeHeight 
                                 relatedBy:NSLayoutRelationEqual 
                                    toItem:nil 
                                 attribute:NSLayoutAttributeNotAnAttribute 
                                multiplier:0.f 
                                 constant:100];

[self addConstraint:_descriptionHeightConstraint];

In the setBounds method, I then changed the value of the constant.

-(void) setBounds:(CGRect)bounds
{
    [super setBounds:bounds];

    _descriptionTextView.frame = bounds;
    CGSize descriptionSize = _descriptionTextView.contentSize;

    [_descriptionHeightConstraint setConstant:descriptionSize.height];

    [self layoutIfNeeded];
}
pkamb
  • 33,281
  • 23
  • 160
  • 191
AndroC
  • 4,758
  • 2
  • 46
  • 69
  • 4
    You may also update the constraint in 'textViewDidChange:' of the UITextViewDelegate – LK__ Aug 05 '14 at 21:47
  • 3
    Nice solution. Note that you could also create the constraint in Interface Builder, and connect it using an outlet. Combined with using `textViewDidChange` this should save some hassle subclassing and writing code… – Bob Vork Nov 11 '14 at 15:06
  • 3
    Keep in mind that `textViewDidChange:` will not be called when adding text to the UITextView programmatically. – wanderlust Oct 01 '15 at 00:38
  • @BobVork suggestion works well XCODE 11/ iOS13, set constraint constant when text view value set in viewWillAppear and update in textViewDidChange. – ptc Feb 07 '20 at 05:30
31

You can do it through storyboard, just disable "Scrolling Enabled":)

StoryBoard

DaNLtR
  • 561
  • 5
  • 21
20

I've found it's not entirely uncommon in situations where you may still need isScrollEnabled set to true to allow a reasonable UI interaction. A simple case for this is when you want to allow an auto expanding text view but still limit it's maximum height to something reasonable in a UITableView.

Here's a subclass of UITextView I've come up with that allows auto expansion with auto layout but that you could still constrain to a maximum height and which will manage whether the view is scrollable depending on the height. By default the view will expand indefinitely if you have your constraints setup that way.

import UIKit

class FlexibleTextView: UITextView {
    // limit the height of expansion per intrinsicContentSize
    var maxHeight: CGFloat = 0.0
    private let placeholderTextView: UITextView = {
        let tv = UITextView()

        tv.translatesAutoresizingMaskIntoConstraints = false
        tv.backgroundColor = .clear
        tv.isScrollEnabled = false
        tv.textColor = .disabledTextColor
        tv.isUserInteractionEnabled = false
        return tv
    }()
    var placeholder: String? {
        get {
            return placeholderTextView.text
        }
        set {
            placeholderTextView.text = newValue
        }
    }

    override init(frame: CGRect, textContainer: NSTextContainer?) {
        super.init(frame: frame, textContainer: textContainer)
        isScrollEnabled = false
        autoresizingMask = [.flexibleWidth, .flexibleHeight]
        NotificationCenter.default.addObserver(self, selector: #selector(UITextInputDelegate.textDidChange(_:)), name: Notification.Name.UITextViewTextDidChange, object: self)
        placeholderTextView.font = font
        addSubview(placeholderTextView)

        NSLayoutConstraint.activate([
            placeholderTextView.leadingAnchor.constraint(equalTo: leadingAnchor),
            placeholderTextView.trailingAnchor.constraint(equalTo: trailingAnchor),
            placeholderTextView.topAnchor.constraint(equalTo: topAnchor),
            placeholderTextView.bottomAnchor.constraint(equalTo: bottomAnchor),
        ])
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    override var text: String! {
        didSet {
            invalidateIntrinsicContentSize()
            placeholderTextView.isHidden = !text.isEmpty
        }
    }

    override var font: UIFont? {
        didSet {
            placeholderTextView.font = font
            invalidateIntrinsicContentSize()
        }
    }

    override var contentInset: UIEdgeInsets {
        didSet {
            placeholderTextView.contentInset = contentInset
        }
    }

    override var intrinsicContentSize: CGSize {
        var size = super.intrinsicContentSize

        if size.height == UIViewNoIntrinsicMetric {
            // force layout
            layoutManager.glyphRange(for: textContainer)
            size.height = layoutManager.usedRect(for: textContainer).height + textContainerInset.top + textContainerInset.bottom
        }

        if maxHeight > 0.0 && size.height > maxHeight {
            size.height = maxHeight

            if !isScrollEnabled {
                isScrollEnabled = true
            }
        } else if isScrollEnabled {
            isScrollEnabled = false
        }

        return size
    }

    @objc private func textDidChange(_ note: Notification) {
        // needed incase isScrollEnabled is set to true which stops automatically calling invalidateIntrinsicContentSize()
        invalidateIntrinsicContentSize()
        placeholderTextView.isHidden = !text.isEmpty
    }
}

As a bonus there's support for including placeholder text similar to UILabel.

Michael Link
  • 301
  • 2
  • 3
  • I'm tryed your solution and it's really works. Cause i'm from 2022, some code lines should be updated to a new style, but your thought, your code is really a solution. And impact from me: i just added a 2 constrains `greaterThanOrEqualToConstant` and `lessThanOrEqualToConstant` to `flexibleTextView` in my VC and sets priority for them aaaand yes, it's works good. Thank you – Koder 228 Jun 30 '22 at 08:27
10

I see multiple answers suggest simply turning off scrollEnabled. This is the best solution. I’m writing this answer to explain why it works.

UITextView implements the intrinsicContentSize property only if scrollEnabled == NO. The disassembly of the getter method looks like this:

- (CGSize)intrinsicContentSize {
  if (self.scrollEnabled) {
    return CGSizeMake(UIViewNoIntrinsicMetric, UIViewNoIntrinsicMetric);
  } else {
    // Calculate and return intrinsic content size based on current width.
  }
}

That means you just need to make sure the width of the text view is constrained enough and then you can make use of the intrinsic content height, either via Auto Layout content hugging/compression resistance priorities or directly using the value during manual layout.

Unfortunately, this behavior is not documented. Apple could have easily saved us all some headaches… no need for an extra height constraint, subclassing, etc.

fumoboy007
  • 5,345
  • 4
  • 32
  • 49
7

You can also do it without subclassing UITextView. Have a look at my answer to How do I size a UITextView to its content on iOS 7?

Use the value of this expression:

[textView sizeThatFits:CGSizeMake(textView.frame.size.width, CGFLOAT_MAX)].height

to update the constant of the textView's height UILayoutConstraint.

Community
  • 1
  • 1
ma11hew28
  • 121,420
  • 116
  • 450
  • 651
  • 3
    Where are you doing this and are you doing anything else to make sure the UITextView is all set up? I am doing this, and the text view itself sizes, but the text itself gets cut off half-way down the height of the UITextView. The text is set programmatically right before doing your stuff above. – chadbag Dec 08 '13 at 08:39
  • I found this more generally useful than the scrollEnabled = NO trick, if you want to set width manually. – addlistener Dec 22 '14 at 13:54
4

This more of a very important comment

Key to understanding why vitaminwater's answer works are three things:

  1. Know that UITextView is a subclass of UIScrollView class
  2. Understand how ScrollView works and how its contentSize is calculated. For more see this here answer and its various solutions and comments.
  3. Understand what contentSize is and how its calculated. See here and here. It might also help that setting contentOffset is likely nothing but:

func setContentOffset(offset: CGPoint)
{
    CGRect bounds = self.bounds
    bounds.origin = offset
    self.bounds = bounds
}

For more see objc scrollview and understanding scrollview


Combining the three together you'd easily understand that you need allow the the textView's intrinsic contentSize to work along AutoLayout constraints of the textView to drive the logic. It's almost as if you're textView is functioning like a UILabel

To make that happen you need to disable scrolling which basically means the scrollView's size, the contentSize's size and in case of adding a containerView, then the containerView's size would all be the same. When they're the same you have NO scrolling. And you'd have 0 contentOffset. Having 0 contentOffSet means you've not scrolled down. Not even a 1 point down! As a result the textView will be all stretched out.

It's also worth nothing that 0 contentOffset means that the scrollView's bounds and frame are identical. If you scroll down 5 points then your contentOffset would be 5, while your scrollView.bounds.origin.y - scrollView.frame.origin.y would be equal to 5

mfaani
  • 33,269
  • 19
  • 164
  • 293
4

I needed a text view that would automatically grow up until a certain maximum height, then become scrollable. Michael Link's answer worked great but I wanted to see if I could come up with something a bit simpler. Here's what I came up with:

Swift 5.3, Xcode 12

class AutoExpandingTextView: UITextView {

    private var heightConstraint: NSLayoutConstraint!

    var maxHeight: CGFloat = 100 {
        didSet {
            heightConstraint?.constant = maxHeight
        }
    }

    private var observer: NSObjectProtocol?

    override init(frame: CGRect, textContainer: NSTextContainer?) {
        super.init(frame: frame, textContainer: textContainer)
        commonInit()
    }

    required init?(coder: NSCoder) {
        super.init(coder: coder)
        commonInit()
    }

    private func commonInit() {
        heightConstraint = heightAnchor.constraint(equalToConstant: maxHeight)

        observer = NotificationCenter.default.addObserver(forName: UITextView.textDidChangeNotification, object: nil, queue: .main) { [weak self] _ in
            guard let self = self else { return }
            self.heightConstraint.isActive = self.contentSize.height > self.maxHeight
            self.isScrollEnabled = self.contentSize.height > self.maxHeight
            self.invalidateIntrinsicContentSize()
        }
    }
}


NSExceptional
  • 1,368
  • 15
  • 12
3

An important thing to note:

Since UITextView is a subclass of UIScrollView, it is subject to the automaticallyAdjustsScrollViewInsets property of UIViewController.

If you are setting up the layout and the TextView is the the first subview in a UIViewControllers hierarchy, it will have its contentInsets modified if automaticallyAdjustsScrollViewInsets is true sometimes causing unexpected behaviour in auto layout.

So if you're having problems with auto layout and text views, try setting automaticallyAdjustsScrollViewInsets = false on the view controller or moving the textView forward in the hierarchy.

DaveIngle
  • 31
  • 2
1

Plug and Play Solution - Xcode 9

Autolayout just like UILabel, with the link detection, text selection, editing and scrolling of UITextView.

Automatically handles

  • Safe area
  • Content insets
  • Line fragment padding
  • Text container insets
  • Constraints
  • Stack views
  • Attributed strings
  • Whatever.

A lot of these answers got me 90% there, but none were fool-proof.

Drop in this UITextView subclass and you're good.


#pragma mark - Init

- (instancetype)initWithFrame:(CGRect)frame textContainer:(nullable NSTextContainer *)textContainer
{
    self = [super initWithFrame:frame textContainer:textContainer];
    if (self) {
        [self commonInit];
    }
    return self;
}

- (instancetype)initWithCoder:(NSCoder *)aDecoder
{
    self = [super initWithCoder:aDecoder];
    if (self) {
        [self commonInit];
    }
    return self;
}

- (void)commonInit
{
    // Try to use max width, like UILabel
    [self setContentCompressionResistancePriority:UILayoutPriorityRequired forAxis:UILayoutConstraintAxisHorizontal];
    
    // Optional -- Enable / disable scroll & edit ability
    self.editable = YES;
    self.scrollEnabled = YES;
    
    // Optional -- match padding of UILabel
    self.textContainer.lineFragmentPadding = 0.0;
    self.textContainerInset = UIEdgeInsetsZero;
    
    // Optional -- for selecting text and links
    self.selectable = YES;
    self.dataDetectorTypes = UIDataDetectorTypeLink | UIDataDetectorTypePhoneNumber | UIDataDetectorTypeAddress;
}

#pragma mark - Layout

- (CGFloat)widthPadding
{
    CGFloat extraWidth = self.textContainer.lineFragmentPadding * 2.0;
    extraWidth +=  self.textContainerInset.left + self.textContainerInset.right;
    if (@available(iOS 11.0, *)) {
        extraWidth += self.adjustedContentInset.left + self.adjustedContentInset.right;
    } else {
        extraWidth += self.contentInset.left + self.contentInset.right;
    }
    return extraWidth;
}

- (CGFloat)heightPadding
{
    CGFloat extraHeight = self.textContainerInset.top + self.textContainerInset.bottom;
    if (@available(iOS 11.0, *)) {
        extraHeight += self.adjustedContentInset.top + self.adjustedContentInset.bottom;
    } else {
        extraHeight += self.contentInset.top + self.contentInset.bottom;
    }
    return extraHeight;
}

- (void)layoutSubviews
{
    [super layoutSubviews];
    
    // Prevents flashing of frame change
    if (CGSizeEqualToSize(self.bounds.size, self.intrinsicContentSize) == NO) {
        [self invalidateIntrinsicContentSize];
    }
    
    // Fix offset error from insets & safe area
    
    CGFloat textWidth = self.bounds.size.width - [self widthPadding];
    CGFloat textHeight = self.bounds.size.height - [self heightPadding];
    if (self.contentSize.width <= textWidth && self.contentSize.height <= textHeight) {
        
        CGPoint offset = CGPointMake(-self.contentInset.left, -self.contentInset.top);
        if (@available(iOS 11.0, *)) {
            offset = CGPointMake(-self.adjustedContentInset.left, -self.adjustedContentInset.top);
        }
        if (CGPointEqualToPoint(self.contentOffset, offset) == NO) {
            self.contentOffset = offset;
        }
    }
}

- (CGSize)intrinsicContentSize
{
    if (self.attributedText.length == 0) {
        return CGSizeMake(UIViewNoIntrinsicMetric, UIViewNoIntrinsicMetric);
    }
    
    CGRect rect = [self.attributedText boundingRectWithSize:CGSizeMake(self.bounds.size.width - [self widthPadding], CGFLOAT_MAX)
                                                    options:NSStringDrawingUsesLineFragmentOrigin
                                                    context:nil];
    
    return CGSizeMake(ceil(rect.size.width + [self widthPadding]),
                      ceil(rect.size.height + [self heightPadding]));
}
Community
  • 1
  • 1
beebcon
  • 6,893
  • 5
  • 25
  • 27
0

vitaminwater's answer is working for me.

If your textview's text is bouncing up and down during edit, after setting [textView setScrollEnabled:NO];, set Size Inspector > Scroll View > Content Insets > Never.

Hope it helps.

Baron Ch'ng
  • 181
  • 8
0

Place hidden UILabel underneath your textview. Label lines = 0. Set constraints of UITextView to be equal to the UILabel (centerX, centerY, width, height). Works even if you leave scroll behaviour of textView.

Yuriy
  • 106
  • 2
  • 3
-1

BTW, I built an expanding UITextView using a subclass and overriding intrinsic content size. I discovered a bug in UITextView that you might want to investigate in your own implementation. Here is the problem:

The expanding text view would grow down to accommodate the growing text if you type single letters at a time. But if you paste a bunch of text into it, it would not grow down but the text would scroll up and the text at the top was out of view.

The solution: Override setBounds: in your subclass. For some unknown reason, the pasting caused the bounds.origin.y value to be non-zee (33 in every case that I saw). So I overrode setBounds: to always set the bounds.origin.y to zero. Fixed the problem.

-1

Here's a quick solution:

This problem may occur if you have set clipsToBounds property to false of your textview. If you simply delete it, the problem goes away.

myTextView.clipsToBounds = false //delete this line
Eray Alparslan
  • 806
  • 7
  • 12
-3
Obj C:

#import <UIKit/UIKit.h>

@interface ViewController : UIViewController

@property (nonatomic) UITextView *textView;
@end



#import "ViewController.h"

@interface ViewController ()

@end

@implementation ViewController

@synthesize textView;

- (void)viewDidLoad{
    [super viewDidLoad];
    [self.view setBackgroundColor:[UIColor grayColor]];
    self.textView = [[UITextView alloc] initWithFrame:CGRectMake(30,10,250,20)];
    self.textView.delegate = self;
    [self.view addSubview:self.textView];
}

- (void)didReceiveMemoryWarning{
    [super didReceiveMemoryWarning];
}

- (void)textViewDidChange:(UITextView *)txtView{
    float height = txtView.contentSize.height;
    [UITextView beginAnimations:nil context:nil];
    [UITextView setAnimationDuration:0.5];

    CGRect frame = txtView.frame;
    frame.size.height = height + 10.0; //Give it some padding
    txtView.frame = frame;
    [UITextView commitAnimations];
}

@end
Alvin George
  • 14,148
  • 92
  • 64