TextKit的一些介紹在這里就不多說了,相關(guān)的信息可以看這里。這篇文章主要講文本分頁和遇到的問題。
TextKit中主要涉及的就三個(gè)類,實(shí)現(xiàn)分頁也用到這是三個(gè)。
NSTextStorage
NSLayoutManager
NSTextContainer
主要的思路就是:
- NSTextStorage 存儲要分段的文本信息
- NSTextStorage 設(shè)置 NSLayoutManager
- 在NSLayoutManager 中添加 NSTextContainer
- 獲取NSTextContainer 顯示的文本長度
- 返回分段信息
這個(gè)思路跟CoreText的分段思路差不多,都是獲取一定范圍內(nèi)的可見文字的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;
}
分頁問題解決了,但是在文本渲染的時(shí)候卻出現(xiàn)了問題。
對于TextView來時(shí),設(shè)置富文本有兩個(gè)方式,一種是通過NSTextStorage設(shè)置,一種是直接用attributedText設(shè)置,但問題來了同樣的NSMutableAttributedString,兩種方式渲染出來的效果居然不一樣。

attributedText設(shè)置的行距會比NSTextStorage設(shè)置的行距大。這就導(dǎo)致用TextKit分頁的結(jié)果,用attributedText來設(shè)置渲染就會出現(xiàn)顯示不全的問題。但是如果文本為英文就沒問題。

再經(jīng)過一番研究后發(fā)現(xiàn)這是字體造成的,中文如果用<code>[UIFont systemFontOfSize:20]</code>就會出現(xiàn)這種問題,只要換了字體就行了。其中在系統(tǒng)提供的字體中,能夠完美使用的有下面幾個(gè),
Heiti SC 黑體-簡
Heiti TC 黑體-繁
PingFang TC 平方-簡
PingFang HK 平方-繁
PingFang SC 平方-繁
</br>
提供一個(gè)簡單的demo,寫的比較簡單,不過能說明問題
CoreText分頁
下面也提供一下CoreText的分頁方法,畢竟CoreText分頁的速度會快一點(diǎn),同樣在設(shè)置字體的時(shí)候,中文內(nèi)容要用<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) {
//設(shè)置路徑
CTFrameRef frame = CTFramesetterCreateFrame(framesetter, CFRangeMake(textPos, 0), path, NULL);
//生成frame
CFRange frameRange = CTFrameGetVisibleStringRange(frame);
NSRange ra = NSMakeRange(frameRange.location, frameRange.length);
//獲取范圍并轉(zhuǎn)換為NSRange,然后以NSAttributedString形式保存
[pagingResult addObject:[str attributedSubstringFromRange:ra]];
//移動當(dāng)前文本位置
textPos += frameRange.length;
CFRelease(frame);
}
CGPathRelease(path);
CFRelease(framesetter);
return pagingResult;
}
簡單的demo:demo地址