boundingRectWithSize不复制UITextView

我在一个项目中的要求是UITextView的字体大小应该根据UITextView的内容减less。 所以我正在尝试使用boundingRectWithSize来估计文本的大小。

问题是,我得到的字体大小有点太大,文本的一部分不会被剪切。

我的function:

  -(BOOL)updateTextViewFontSizeForText:(NSString*)text{ float fontSize = self.maximumFontSizeInPoints; self.font = [self.font fontWithSize:fontSize]; CGSize tallerSize ; CGSize stringSize ; do { if (fontSize <= self.minimumFontSizeInPoints) // it just won't fit return NO; fontSize -= 1.0; self.font = [self.font fontWithSize:fontSize]; NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init]; [paragraphStyle setLineBreakMode:NSLineBreakByWordWrapping]; NSDictionary *attributes = @{ NSFontAttributeName: self.font, NSParagraphStyleAttributeName : paragraphStyle }; tallerSize = CGSizeMake(self.frame.size.width,self.frame.size.height-16);// the 16 is given because uitextview adds some offset stringSize = [text boundingRectWithSize:CGSizeMake(self.contentSize.width,CGFLOAT_MAX) options:NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading attributes:attributes context:nil].size; }while(stringSize.height >= tallerSize.height); if ([self.onTextChangDelegate respondsToSelector:@selector(onTextChangDelegate)]) { [self.onTextChangDelegate onTextChanged:text]; } return YES; } 

当我尝试做同样的事情时遇到了同样的问题。

问题是UITextView如何运行与lineingRectWithSize相比的换行符。 你可以在这里阅读更多的细节: https : //developer.apple.com/library/mac/documentation/Cocoa/Conceptual/TextLayout/Concepts/CalcTextLayout.html

但是,你实际上可以计算确切的大小! 基本上有两个UITextView属性,你需要考虑到,以获得正确的大小估计。 第一个是textContainer.lineFragmentPadding ,第二个是textContainerInset

首先, textContainer.lineFragmentPadding :您可能已经注意到,您的大小通常总是偏离10px ,这是因为系统默认值是5px 。 当你计算你的估计大小时,你需要从你检查的大小中减去这个值,并在你有最终值时加回来。

其次, textContainerInset 。 这是一个UIEdgeInset ,你需要添加回你的最终计算值来匹配系统。

这是基于我如何解决问题的代码:

 - (CGSize)sizeThatFits:(CGSize)size CGFloat lineFragmentPaddings = self.textContainer.lineFragmentPadding * 2; CGFloat horzPadding = self.textContainerInset.left + self.textContainerInset.right + lineFragmentPaddings; CGFloat vertPadding = self.textContainerInset.top + self.textContainerInset.bottom; size.width -= horzPadding; CGRect boundingRect = [attributedText boundingRectWithSize:size options:NSStringDrawingUsesLineFragmentOrigin context:nil]; size = boundingRect.size; // I found through debugging that adding 0.25 rounded // matches sizeThatFits: identically. Not sure why… size.width += horzPadding + 0.25; size.height += vertPadding + 0.25; size = CGSizeRound(size); return size; } 

请注意, CGSizeRound只是我写的一个自定义函数, CGSizeRoundwidthheight CGSize到最接近的0.5

为了比较,如果你创build第二个UITextView ,并确保textContainer.lineFragmentPaddingtextContainerInset是相同的,你应该看到几乎相同的值,最接近的0.5

关于计算一个合适的pointSize的问题,这是一些伪代码:

 CGFloat pointSize = 64; CGFloat minPointSize = 32; CGFloat decrementor = 4; CGFloat padding = self.textContainerInset.left + self.textContainerInset.right + lineFragmentPaddings; CGFloat actualWidth = self.maxTextViewSize.width - padding * 2; CGRect boundingRect = CGRectZero; BOOL isValidPointSize = NO; do { if (pointSize < minPointSize) { pointSize = minPointSize; boundingRect.size.height = self.maxTextViewSize.height; isValidPointSize = YES; } else { NSDictionary *defaultAttributes = [self.customTextStorage defaultAttributesForPointSize:pointSize]; NSAttributedString *attrString = [[NSAttributedString alloc] initWithString:string attributes:defaultAttributes]; boundingRect = [attrString boundingRectWithSize:CGSizeMake(actualWidth, 1024) options:NSStringDrawingUsesLineFragmentOrigin context:nil]; // is the height to big? if (boundingRect.size.height > self.maxTextViewSize.height) { // reduce the point size for next iteration of loop pointSize -= decrementor; } // passes height test else { isValidPointSize = YES; } } } while (!isValidPointSize); return pointSize; 

再一次,以上是基于我的实现的伪代码(不只是代替你所拥有的东西)。 希望这可以帮助!

试试这个

 UITextView *textViewObj;//initialise textview. textViewObj.autoresizesSubviews = NO; textViewObj.autoresizingMask = UIViewAutoresizingNone; 

这是真的在迅速工作,得到textview的原始高度..试试这个让

 size = cellQueue.contentLbl.sizeThatFits(CGSizeMake(cellQueue.contentLbl.frame.size.width,CGFloat(MAXFLOAT))) cellQueue.heightConstraintContentLbl.constant = size.height