Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

UITextView content size different in iOS7

I am using an UITextView that will be expandable by taping a "more" button. The problem is the following:

On iOS6 I use this,

self.DescriptionTextView.text =  @"loong string";

if(self.DescriptionTextView.contentSize.height>self.DescriptionTextView.frame.size.height) { 
    //set up the more button
}

The problem is that on iOS7 the contentSize.height returns a different value (far smaller) than the value it returns on iOS6. Why is this? How to fix it?

like image 900
user1028028 Avatar asked Sep 27 '13 09:09

user1028028


3 Answers

The content size property no longer works as it did on iOS 6. Using sizeToFit as others suggest may or may not work depending on a number of factors.

It didn't work for me, so I use this instead:

- (CGFloat)measureHeightOfUITextView:(UITextView *)textView
{
    if (floor(NSFoundationVersionNumber) > NSFoundationVersionNumber_iOS_6_1)
    {
        // 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;
    }
}
like image 132
tarmes Avatar answered Nov 13 '22 16:11

tarmes


Try the answer in the following link, layoutIfNeeded should be called before contentSize.

iOS7 UITextView contentsize.height alternative

The answer:

In iOS7, UITextView uses NSLayoutManager to layout text:

// If YES, then the layout manager may perform glyph generation and layout for a given portion of the text, without having glyphs or layout for preceding portions.  The default is NO.  Turning this setting on will significantly alter which portions of the text will have glyph generation or layout performed when a given generation-causing method is invoked.  It also gives significant performance benefits, especially for large documents.
@property(NS_NONATOMIC_IOSONLY) BOOL allowsNonContiguousLayout;

disable allowsNonContiguousLayout to fix contentSize :

textView.layoutManager.allowsNonContiguousLayout = NO;
like image 44
nova Avatar answered Nov 13 '22 14:11

nova


This link seems to have the answer.

You must use sizeToFit before using contentSize.

like image 2
Puneet Sharma Avatar answered Nov 13 '22 14:11

Puneet Sharma