此法计算不准确:
CGRect frame = self.serTextView.frame;
frame.size.height = self.serTextView.contentSize.height;
self.serTextView.frame = frame;
正确方法是使用NSString的boundingRectWithSize方法计算:
CGRect frame = weakSelf.frame;
frame.size.height = [self.attributedText boundingRectWithSize: CGSizeMake(frame.size.width, CGFLOAT_MAX) options: NSStringDrawingTruncatesLastVisibleLine | NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading context:nil].size.height;
weakSelf.frame = frame;
strongSelf.attributedText = supportAttributeStr;
[strongSelf sizeToFit];
NSString *htmlString = @"<h1>Header</h1><h2>Subheader</h2><p>Some<em>text</em></p><img src='http://blogs.babble.com/famecrawler/files/2010/11/mickey_mouse-1097.jpg' width=70 height=100 />";
NSAttributedString*attributedString = [[NSAttributedString alloc] initWithData:[htmlString dataUsingEncoding: NSUnicodeStringEncoding] options: @{NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType } documentAttributes: nil error: nil];
textView.attributedText = attributedString;
- (BOOL) textView: (UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText: (NSString*)text {
NSInteger maxLineNum = 4;
NSString *textString = @"Text";
CGSize fontSize = [textString sizeWithAttributes: @{NSFontAttributeName: textView.font}];
NSString* newText = [textView.text stringByReplacingCharactersInRange: range withString: text];
CGSize tallerSize = CGSizeMake(textView.frame.size.width-15, textView.frame.size.height*2);
CGSize newSize = [newText boundingRectWithSize: tallerSize options: NSStringDrawingUsesLineFragmentOrigin attributes: @{NSFontAttributeName: textView.font} context: nil].size;
NSInteger newLineNum = newSize.height / fontSize.height;
if ([text isEqualToString:@"\n"]) {
newLineNum += 1;
}
if((newLineNum <= maxLineNum) && newSize.width < textView.frame.size.width-15)
{
return YES;
}
else{
return NO;
}
}
boundingRectWithSize:options:context:
返回文本绘制所占据的矩形空间。
- (CGRect)boundingRectWithSize:(CGSize)sizeoptions:(NSStringDrawingOptions)optionscontext:(NSStringDrawingContext*)context
参数
size
宽高限制,用于计算文本绘制时占据的矩形块。
The width and height constraints to apply when computing the string’s bounding rectangle.
options
文本绘制时的附加选项。可能取值请参考 “NSStringDrawingOptions”。
context
context上下文。包括一些信息,例如如何调整字间距以及缩放。最终,该对象包含的信息将用于文本绘制。该参数可为 nil 。
返回值
一个矩形,大小等于文本绘制完将占据的宽和高。
讨论
可以使用该方法计算文本绘制所需的空间。size 参数是一个constraint,用于在绘制文本时作为参考。但是,如果绘制完整个文本需要更大的空间,则返回的矩形大小可能比 size更大。一般,绘制时会采用constraint 提供的宽度,但高度则会根据需要而定。
特殊情况
为了计算文本块的大小,该方法采用默认基线。如果NSStringDrawingUsesLineFragmentOrigin未指定,矩形的高度将被忽略,同时使用单线绘制。(由于一个 bug,在 iOS6中,宽度会被忽略)
兼容性
iOS 6.0 以后支持。
声明于
NSStringDrawing.
另外,关于参数(NSStringDrawingOptions)options
typedef NS_ENUM(NSInteger,NSStringDrawingOptions) {
NSStringDrawingTruncatesLastVisibleLine = 1 << 5, // Truncates andadds the ellipsis character to the last visible line if the text doesn't fitinto the bounds specified. Ignored if NSStringDrawingUsesLineFragmentOrigin isnot also set.
NSStringDrawingUsesLineFragmentOrigin =1 << 0, // The specified origin is the linefragment origin, not the base line origin
NSStringDrawingUsesFontLeading =1 << 1, // Uses the font leading for calculatingline heights
NSStringDrawingUsesDeviceMetrics =1 << 3, // Uses image glyph bounds instead oftypographic bounds
} NS_ENUM_AVAILABLE_IOS(6_0);
NSStringDrawingTruncatesLastVisibleLine:
如果文本内容超出指定的矩形限制,文本将被截去并在最后一个字符后加上省略号。如果没有指定NSStringDrawingUsesLineFragmentOrigin选项,则该选项被忽略。
NSStringDrawingUsesLineFragmentOrigin:
绘制文本时使用 line fragment origin 而不是 baseline origin。
The origin specified when drawing the string is the line fragment origin and not the baseline origin.
NSStringDrawingUsesFontLeading:
计算行高时使用行距。(译者注:字体大小+行间距=行距)
NSStringDrawingUsesDeviceMetrics:
计算布局时使用图元字形(而不是印刷字体)。
Use the image glyph bounds(instead of the typographic bounds) when computing layout.
问题原因:
将Text做宽高计算时,高度值容易得出小数数值,而页面绘制均是基于整数像素点绘制,对于小数点部分,系统会做舍去处理(即便有缩放),固留下高度不定的未绘制区域(为黑色)。
解决方案:
将计算出来的高度值做向下取整处理即可。
CGRect labelFrame = [content boundingRectWithSize: size options: NSStringDrawingTruncatesLastVisibleLine | NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading attributes: _postContentTextView.typingAttributes context: nil];
labelSize = labelFrame.size;
labelSize.height = ceilf(labelSize.height);
TextKit学习(四)通过boundingRectWithSize:options:attributes:context:计算文本尺寸
http://www.tuicool.com/articles/73Y7Zb
动态计算UITextView的高度
http://blog.sina.com.cn/s/blog_6ae8b50d0100zl2u.html
Display html text in uitextview
http://stackoverflow.com/questions/2454067/display-html-text-in-uitextview
一文让你彻底了解iOS字体相关知识
http://ios.jobbole.com/83939/?utm_source=tuicool&utm_medium=referral