UITextView that expands to text using auto layout

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.


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];
}

Just got into this issue, I don't know if I'm off topic, but if you set your UITextView to "not" scrollable:

[textView setScrollEnabled:NO];

it will be able to calculate an intrinsic size, thus allowing auto layout to move the other elements by itself, then it's up to you to setup the constraints right.

(on iOS 7)


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
链接地址: http://www.djcxy.com/p/28282.html

上一篇: 动态UIView高度与iOS 6中的自动布局

下一篇: 使用自动布局扩展为文本的UITextView