为了将长字符串布局到页面中,我可以使用 CTFramesetterCreateFrame
来创建 CTFrameRef
,然后向前移动字符串中的起始索引以创建下一个 CTFrameRef
。这很容易,因为开始索引向前移动,并且 Core Text API 原生支持这种布局。
现在我陷入了一种情况,我想翻到上一页。
比如长字符串的长度是1000,现在当前页(或者CTFrameRef
)的起始索引是500,我想翻到上一页,怎么办知道从什么索引开始?我无法缓存每个页面的所有索引或从字符串的开头计算,因为字符串可能非常长以至于无法放入内存(我需要逐 block 从文件中读取字符串) .我扫描了CT*
API,没有这样的API支持向后布局文本。
对此有什么想法吗?
最佳答案
没有 API 的原因是除了尝试通过反复试验排版整个页面以找到最佳起始索引之外,没有有效的上下文无关的方法来执行此操作,您可以想象这将是一个集约化经营。
如果你的文本的每一页都有一个设置的宽度,并且只是一个矩形的 CTFrame,你可以这样做:
- “估计”上一页的字符串范围(例如,假设它与当前页面的长度相同。
- 以合理的大因素(例如长度的 1.5/2 倍)超出该估计,直到合理。选择超出范围,使其从段落开头开始。
- 像往常一样创建一个具有该范围的框架,但使框架比平时大得多。
- 从框架中获取行信息,并从末尾开始逐行返回计算高度。
- 您可以从适合的第一行的索引开始找到实际的上一页,并使用它来创建实际的 CTFrame。
虽然这应该可行,但我仍然建议您尽可能找到避免这种情况的方法。请注意,一旦您拥有更复杂的分页算法,这种情况就会崩溃,即使在这种情况下,它也会使用 1.5/2x 内存。以下是有关如何执行此操作的一些建议:
缓存索引(至少到当前位置)。每个页面大概可以容纳 1000 个字符,所以你的缓存大小将是整个文本大小的 0.1%,你必须在至少一次你第一次显示文本。您可以通过为每 n 页存储索引来使缓存更小。
如果适用,将您的字符串分成逻辑子字符串,例如基于分页符或分节符,然后将每个子字符串作为一个整体排版为一系列页面。
关于ios - 如何使用 Core Text 向后布局文本?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9647530/