在iOS上使用TextKit进行文本分页
Textkit的框架
对于显示在视图上的字符串,它需要经历几个过程:存储字符串->排版->显示。
TextStorage类是用于存储字符串的容器,因此首先必须将字符串(无论是纯文本还是富文本格式)打包到TextStorage中 ,然后LayoutManager将管理文本的布局,之后是TextContainer类将控制位置和页面大小,请注意TextContainer和TextView的大小均不正确,这将在本文后面提到。
设置完所有内容后,您可以使用UITextView或UILabel在视图上显示文本。 在实际开发中,我的建议是在某些尺寸问题的情况下使用TextView 。
分页
使用TextKit进行分页非常简单。 根据Apple的官方文档,LayoutManager和TextContainer可以一起完成分页工作,同时,如果您有其他要求,则需要一种算法。
从上图中, LayoutManager从TextStorage读取字符串,并根据添加到LayoutManager的TextContainer的数量执行页面布局。
如果只有一个TextContainer ,则将仅排版第一页的数据,而另一页将被丢弃。 如果有多个TextContainer ,则可以完成大文本分页。
码
// 1. 从文件中读取字符串。
NSString * textString = [[NSString alloc] initWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@“ Text” ofType:@“ txt”]编码:NSUTF8StringEncoding错误:无];
// 2. 将字符串打包到存储中。
NSTextStorage *存储= [[NSTextStorage alloc] initWithString:textString];
// 3. 为存储添加布局管理。
NSLayoutManager * layoutManager = [[NSLayoutManager alloc] init];
[存储addLayoutManager:layoutManager];
同时(是)
{
// 4. 将具有确定大小的TextContainer添加到LayoutManager
NSTextContainer * textContainer = [[[NSTextContainer alloc] initWithSize:CGSizeMake(sTextViewWidth,sTextViewHeight)]];
[layoutManager addTextContainer:textContainer];
// 5. 将TextContainer绑定到TextView
UITextView * textView = [[UITextView alloc] initWithFrame:CGRectMake(0,0,sTextViewWidth,sTextViewHeight)textContainer:textContainer];
textView.editable = NO;
[scrollView addSubview:textView];
i ++;
// 6. 排版的确定。
NSRange range = [layoutManager glyphRangeForTextContainer:textContainer];
如果(range.length + range.location == textString.length)
打破;
}
PS : “ sTextViewWidth”和“ sTextViewHeight”是Textview的高度和宽度宏。
有一些用于LayoutManager的排版计算的常用方法。
-(NSRange)glyphRangeForTextContainer:(NSTextContainer *)容器;
-(NSRange)glyphRangeForBoundingRect:(CGRect)bounds inTextContainer:(NSTextContainer *)container;
-(CGRect)usedRectForTextContainer:(NSTextContainer *)容器;
最后
Apple不提供反向排版。 因此,如果您需要计算前一页数据,请自行设计一个合适的算法。
问题
在普通文本中找不到此问题,但是在富文本中出现了此问题,具体情况是,当将TextContainer和TextView的大小设置为相同时,最终的显示结果并不完美:页面的几乎所有末端都是不规则的,即使单词的最后一行也将被剪掉一半。
这是我的解决方案:
- 确保TextContainer的大小。 高度比TextView短一行。
- 请小心控制TextView的框架,以使上下边框的值尽可能相等。
- CFBundleDocumentTypes与照片库/相机胶卷
- 在后台每X分钟执行一次function不起作用
- 在某些Apple设备上未收到背景GCM推送通知
- UIImage(contentsOfFile :)返回nil,尽pipe文件存在于caching目录中
- 我应该怎么做才能调用audioPlayerDidFinishPlaying:
- 移动视图与约束
- 如何使用swift将对象数组保存到NSUserDefault?
- 使用.000Z格式化datestring到NSDate
- 当用户按下button显示dateselect器视图和selectdate,然后显示为button标题和进一步closuresdateselect器视图