有没有办法可靠地计算 UITextView 的高度?

Posted

技术标签:

【中文标题】有没有办法可靠地计算 UITextView 的高度?【英文标题】:Is there anyway to reliably calculate the height of a UITextView? 【发布时间】:2012-05-22 05:18:32 【问题描述】:

我试过sizeWithFont:constrainedToSize:lineBreakModesizeToFit,两者都没有返回正确的结果。

属性contentSize应该返回正确的高度,但是直到文本视图呈现到屏幕上它才起作用,并且我需要在文本视图可见之前计算高度(它确定高度UITableViewCell.

有没有人找到任何其他方法,自定义文本视图等,可以正确计算 UITextView 的高度?

编辑 我应该澄清一下,我想要基于文本视图内容的理想高度。

【问题讨论】:

UITextView.frame.size.height? 这确实为我们提供了 UITextView 的高度,但根据其内容,我正在寻找理想的高度。我会更新我的问题。 【参考方案1】:

这是对我有用的代码:

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

让它发挥作用的关键是if (comment.length == 0) comment = @" ";

【讨论】:

这对标签很有效,我以前也用它做标签,但它对 UITextViews 不可靠。 对不起,我还没有为 UITextViews 尝试过。会导致什么问题?【参考方案2】:

在 UITextview 布局之前,高度不可用。在 ios 6 上,addSubview(例如,给 UIScrollView)给它布局值(即 frame.size.height)。在 iOS 7 上,这并不总是发生 - 对于 sizeToFit,同样如此。

我找到了一些解决方案,我更喜欢先执行 sizeToFit 的解决方案,然后是 layoutIfNeeded,然后再读取(现在更改的)高度:

...
[scrollView1 addSubview: myTextView];

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

CGRect frame = myTextView.frame;
...

这是来自已接受的答案here,请参阅注释。我在这里解释的尝试是,这对于添加到 UITableViewCells 而不是 UIScrollViews 的 UITextviews 不应该有效(出于某种原因)。

【讨论】:

这没有意义。【参考方案3】:

当涉及 sizeToFit: 和 layouSubview 的技术不起作用时,我使用这个:

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

【讨论】:

【参考方案4】:

IOS 7 不再支持属性contentSize。试试这个

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

这解决了我的问题。

【讨论】:

以上是关于有没有办法可靠地计算 UITextView 的高度?的主要内容,如果未能解决你的问题,请参考以下文章

iOS依据字符串计算UITextView高度

UITextView vs UILabel 高度计算

UITextView 文字在高度达到 8192.0 后变得不可见

如果要换行的文本中有长字符串,则 sizeWithFont 不会为 UITextView 提供正确的高度

UITableview swift中的UITextview高度

iOS UITextView 高度随文字自己主动添加,并尾随键盘移动