iOS7中UITextView内容大小不同。

15

我正在使用一个 UITextView,通过点击“更多”按钮可以扩展它。但是问题是:

在 iOS6 中,我使用了以下代码:

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

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

问题在于在iOS7上,contentSize.height返回的值(要小得多)与它在iOS6上返回的值不同。 为什么会这样?如何解决?

iOS7上contentSize.height返回值比iOS6上小是因为UITableView计算高度的方式已更改。解决方法是使用-systemLayoutSizeFittingSize:来获取正确的高度。

4个回答

59

内容大小属性在 iOS 6 上的工作方式已经不再适用。根据一些因素,使用其他人建议的 sizeToFit 可能有效,也可能无效。

对我来说它并没有起作用,所以我改用了这个:

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

谢谢,这似乎很好用。你能帮忙回答另一个类似的问题吗?https://dev59.com/OnfZa4cB1Zd3GeqPP0xl - user1028028
使用下一个检查iOS版本很容易:如果(floor(NSFoundationVersionNumber) > NSFoundationVersionNumber_iOS_6_1)。 - JastinBall
2
到目前为止,我看到的最好的解决iOS 7引起的contentSize.height问题的方法。唯一需要提醒的是最好检查系统版本,以防万一snapshotViewAfterScreenUpdates发生变化。 - VGruenhagen
3
我已更新代码以检查系统版本是否为iOS 7。 - tarmes
对我也是同样的问题,但在iOS9上textView.contentSize.height完美地工作了。 :) - Gaurav Borole
显示剩余2条评论

10

请尝试以下链接中的答案,应在调用contentSize之前调用layoutIfNeeded

iOS7 UITextView contentsize.height alternative

答案:

在iOS7中,UITextView使用NSLayoutManager来布局文本:

// 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;

禁用allowsNonContiguousLayout以修复contentSize

textView.layoutManager.allowsNonContiguousLayout = NO;

根据文档,allowsNonContiguousLayout默认设置为false。是否存在某些情况下需要将其设置为true并手动重置呢? - Lope
@Lope 我认为对于自己创建的布局管理器,默认情况下可能是false,但对于TextView创建的布局管理器,默认情况下是true。将其设置回false解决了我的布局问题。谢谢@nova! - Simon

2

这个链接似乎有答案。

在使用contentSize之前,必须使用sizeToFit


1
该链接指出,sizeToFit在iOS 6中可以使用,但是现在在iOS 7中需要一些额外的解决方法。 - TPoschel

0

尝试使用以下代码,它将在iOS6和7中都能正常工作,请尝试。

CGSize myTextViewSize = [self.myTextView sizeThatFits:CGSizeMake(self.myTextView.frame.size.width, FLT_MAX)];
self.myTextView.height = myTextViewSize.height;
NSLog(@"%f", self.myTextView.height);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接