TextKit的一些介绍在这里就不多说了,相关的信息可以看这里。这篇文章主要讲文本分页和遇到的问题。
TextKit中主要涉及的就三个类,实现分页也用到这是三个。
NSTextStorage
NSLayoutManager
NSTextContainer
主要的思路就是:
- NSTextStorage 存储要分段的文本信息
- NSTextStorage 设置 NSLayoutManager
- 在NSLayoutManager 中添加 NSTextContainer
- 获取NSTextContainer 显示的文本长度
- 返回分段信息
这个思路跟CoreText的分段思路差不多,都是获取一定范围内的可见文字的rang,
//TextKit 分页
+ (NSArray *)pagingwithContentString:(NSString *)contentString contentSize:(CGSize)contentSize textAttribute:(NSDictionary *)textAttribute {
NSMutableArray *pagingArray = [NSMutableArray array];
NSMutableAttributedString *orginAttString = [[NSMutableAttributedString alloc] initWithString:contentString attributes:textAttribute];
NSTextStorage *textStorage = [[NSTextStorage alloc] initWithAttributedString:orginAttString];
NSLayoutManager* layoutManager = [[NSLayoutManager alloc] init];
[textStorage addLayoutManager:layoutManager];
while (YES) {
NSTextContainer *textContainer = [[NSTextContainer alloc] initWithSize:contentSize];
[layoutManager addTextContainer:textContainer];
NSRange rang = [layoutManager glyphRangeForTextContainer:textContainer];
if (rang.length <= 0) {
break;
}
NSString *str = [contentString substringWithRange:rang];
NSMutableAttributedString *attStr = [[NSMutableAttributedString alloc] initWithString:str attributes:textAttribute];
[pagingArray addObject:attStr];
}
return pagingArray;
}
分页问题解决了,但是在文本渲染的时候却出现了问题。
对于TextView来时,设置富文本有两个方式,一种是通过NSTextStorage设置,一种是直接用attributedText设置,但问题来了同样的NSMutableAttributedString,两种方式渲染出来的效果居然不一样。
attributedText设置的行距会比NSTextStorage设置的行距大。这就导致用TextKit分页的结果,用attributedText来设置渲染就会出现显示不全的问题。但是如果文本为英文就没问题。
两边的行距一致再经过一番研究后发现这是字体造成的,中文如果用<code>[UIFont systemFontOfSize:20]</code>就会出现这种问题,只要换了字体就行了。其中在系统提供的字体中,能够完美使用的有下面几个,
Heiti SC 黑体-简
Heiti TC 黑体-繁
PingFang TC 平方-简
PingFang HK 平方-繁
PingFang SC 平方-繁
</br>
提供一个简单的demo,写的比较简单,不过能说明问题
CoreText分页
下面也提供一下CoreText的分页方法,毕竟CoreText分页的速度会快一点,同样在设置字体的时候,中文内容要用<code>Heiti</code>或<code>PingFang</code>
//CoreText 分页
+ (NSArray *)coreTextPaging:(NSAttributedString *)str textFrame:(CGRect)textFrame{
NSMutableArray *pagingResult = [NSMutableArray array];
CFAttributedStringRef cfAttStr = (__bridge CFAttributedStringRef)str;
CTFramesetterRef framesetter = CTFramesetterCreateWithAttributedString(cfAttStr);
CGPathRef path = CGPathCreateWithRect(textFrame, NULL);
int textPos = 0;
NSUInteger strLength = [str length];
while (textPos < strLength) {
//设置路径
CTFrameRef frame = CTFramesetterCreateFrame(framesetter, CFRangeMake(textPos, 0), path, NULL);
//生成frame
CFRange frameRange = CTFrameGetVisibleStringRange(frame);
NSRange ra = NSMakeRange(frameRange.location, frameRange.length);
//获取范围并转换为NSRange,然后以NSAttributedString形式保存
[pagingResult addObject:[str attributedSubstringFromRange:ra]];
//移动当前文本位置
textPos += frameRange.length;
CFRelease(frame);
}
CGPathRelease(path);
CFRelease(framesetter);
return pagingResult;
}
简单的demo:demo地址
网友评论