5

I've tried sizeWithFont:constrainedToSize:lineBreakMode and sizeToFit, both of which don't return the correct result.

The property contentSize is supposed to return the correct height, but it doesn't work until the text view is rendered to the screen, and I need to calculate the height before the text view is visible (it determines the height of a UITableViewCell.

Has anyone found any other method, a custom text view or the like, that correctly calculates the height of a UITextView?

EDIT I should clarify that I want the ideal height based upon the text view's content.

Quentamia
  • 3,244
  • 3
  • 33
  • 42

4 Answers4

1

IOS 7 does not supports the property contentSize anymore. Try using this

CGFloat textViewContentHeight = textView.contentSize.height;
textViewContentHeight = ceilf([textView sizeThatFits:textView.frame.size].height + 9);

this fixed my problem.

Vivek Molkar
  • 3,910
  • 1
  • 34
  • 46
gunas
  • 1,889
  • 1
  • 16
  • 29
0

Here is the code that worked for me:

+ (CGFloat)heightOfComment:(NSString *)comment {
    UILabel *label = PrototypeCell.commentLabel;

    // NOTE: The height of the comment should always be at least the height of
    //       one line of text.
    if (comment.length == 0)
        comment = @" ";

    return [comment sizeWithFont:label.font
               constrainedToSize:label.frame.size
                   lineBreakMode:label.lineBreakMode].height;    
}

The key to making it work was if (comment.length == 0) comment = @" ";.

Jeffery Thomas
  • 42,202
  • 8
  • 92
  • 117
0

When the techniques involving sizeToFit: and layouSubview don't work, I use this:

- (CGFloat)measureHeightOfUITextView:(UITextView *)textView
{
    if ([textView respondsToSelector:@selector(snapshotViewAfterScreenUpdates:)])
    {
        // This is the code for iOS 7. contentSize no longer returns the correct value, so
        // we have to calculate it.
        //
        // This is partly borrowed from HPGrowingTextView, but I've replaced the
        // magic fudge factors with the calculated values (having worked out where
        // they came from)

        CGRect frame = textView.bounds;

        // Take account of the padding added around the text.

        UIEdgeInsets textContainerInsets = textView.textContainerInset;
        UIEdgeInsets contentInsets = textView.contentInset;

        CGFloat leftRightPadding = textContainerInsets.left + textContainerInsets.right + textView.textContainer.lineFragmentPadding * 2 + contentInsets.left + contentInsets.right;
        CGFloat topBottomPadding = textContainerInsets.top + textContainerInsets.bottom + contentInsets.top + contentInsets.bottom;

        frame.size.width -= leftRightPadding;
        frame.size.height -= topBottomPadding;

        NSString *textToMeasure = textView.text;
        if ([textToMeasure hasSuffix:@"\n"])
        {
            textToMeasure = [NSString stringWithFormat:@"%@-", textView.text];
        }

        // NSString class method: boundingRectWithSize:options:attributes:context is
        // available only on ios7.0 sdk.

        NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init];
        [paragraphStyle setLineBreakMode:NSLineBreakByWordWrapping];

        NSDictionary *attributes = @{ NSFontAttributeName: textView.font, NSParagraphStyleAttributeName : paragraphStyle };

        CGRect size = [textToMeasure boundingRectWithSize:CGSizeMake(CGRectGetWidth(frame), MAXFLOAT)
                                                  options:NSStringDrawingUsesLineFragmentOrigin
                                               attributes:attributes
                                                  context:nil];

        CGFloat measuredHeight = ceilf(CGRectGetHeight(size) + topBottomPadding);
        return measuredHeight;
    }
    else
    {
        return textView.contentSize.height;
    }
}
tarmes
  • 15,366
  • 10
  • 53
  • 87
-2

Height is not available until the UITextview gets laid out. On iOS 6, addSubview (to a UIScrollView, for example) gave it layout values (i.e. frame.size.height). On iOS 7,this doesn't always happen - and for sizeToFit, the same is true.

I found some solutions, I prefer the one that does sizeToFit, then layoutIfNeeded before reading the (now changed) height:

...
[scrollView1 addSubview: myTextView];

    [myTextView sizeToFit]; //added
    [myTextView layoutIfNeeded]; //added

CGRect frame = myTextView.frame;
...

This is from the accepted answer here, see the notes. My attempt at explanation here is in the case this shouldn't be valid for UITextviews that are added to UITableViewCells instead of UIScrollViews (for some reason).

Community
  • 1
  • 1
Henrik Erlandsson
  • 3,797
  • 5
  • 43
  • 63