【IOS开发基础系列】UITextView专题

2023-10-16 11:42:12 浏览数 (3)

1 常用开发技巧

1.1 常用技巧

1.1.1 boundingRectWithSize动态计算TextView高度(contentSize计算不准确)

此法计算不准确:

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;

1.1.2 sizeToFit动态计算TextView高度

strongSelf.attributedText = supportAttributeStr;

[strongSelf sizeToFit];

1.1.3 显示html内容

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;

1.2 常见问题

1.2.1 UITextView行数限制:输入字符后,判断是否会超过限制行数

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

    }

}  

1.2.2 通过boundingRectWithSize: options: attributes: context:计算文本尺寸

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.

1.2.3 绘制TextView时底部出现高度不定的细微黑线

问题原因:

       将Text做宽高计算时,高度值容易得出小数数值,而页面绘制均是基于整数像素点绘制,对于小数点部分,系统会做舍去处理(即便有缩放),固留下高度不定的未绘制区域(为黑色)。

解决方案:

        将计算出来的高度值做向下取整处理即可。

CGRect labelFrame = [content boundingRectWithSize: size options: NSStringDrawingTruncatesLastVisibleLine | NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading attributes: _postContentTextView.typingAttributes context: nil];

labelSize = labelFrame.size;

labelSize.height = ceilf(labelSize.height);

2 参考链接

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

0 人点赞