如何强制位于UITextView垂直范围之外的字形布局?

时间:2019-04-11 17:36:59

标签: swift uiscrollview uitextview cgrect

这里不需要代码。我需要一些有关如何布局很长的多行字符串的所有字形的指导,以显示在启用滚动的UITextView中。了解一些背景信息的情况。

背景:我有一个很长的多字符串文本,需要在启用滚动的UITextView中显示。我创建了一个函数,该函数可以识别多行字符串中搜索字符串匹配项的CGRect位置,然后将用户动画化为匹配项的CGRect位置。这是通过将匹配文本的CGRect传递到contentOffset来实现的,该动画将滚动到该位置。传递给CGRect的{​​{1}}是使用contentOffset生成的,以确保准确性。换句话说,文本的layoutmanager基于匹配字符串的字形的位置。

但是,如果匹配的搜索字符串的CGRect垂直于UITextView CGRect,则动画实际上会失败。没有任何滚动。好像滚动动画不知道要在哪里找到bounds.height位置才能滚动到匹配的字符串。如果我先手动滚动到UITextView的最底部,然后将动画执行到匹配的搜索字符串的CGRect位置,则可以纠正此问题。在这种情况下,UITextView似乎具有文本布局的完整图片,并且可以准确地找到匹配的搜索字符串CGRect在多行字符串中的位置。

基于上述内容,对我来说很明显,UITextView不会一次布局多行字符串的所有字形。该视图可能以块的形式绘制字形,类似于表视图创建单元格的方式。在我看来,当我手动滚动经过视图的边界到内容垂直大小的最底部时,UITextView能够保留所有字形布局信息。

有没有可用的代码可以有效地布局UITextView的整个内容大小,即使这些字形远不在UITextView的垂直范围之内?看来我需要首先布置所有字形,以防止出现上述错误。

1 个答案:

答案 0 :(得分:1)

出于性能方面的考虑,UITextView的整个内容布局不一定会在您期望的时候确定。

例如,如果您在文本视图中有足够的文本来覆盖可见区域的10倍,则UIKit可能会“推迟”布局文本。毕竟,仅仅因为文本在其中并不意味着用户会滚动到它。

NSLayoutManager提供了几种功能,可让您确保在要访问文本视图时,已对文本视图的全部内容进行了布局(请参见https://developer.apple.com/documentation/uikit/nslayoutmanager):

func ensureGlyphs(forCharacterRange: NSRange)
func ensureGlyphs(forGlyphRange: NSRange)
func ensureLayout(forBoundingRect: CGRect, in: NSTextContainer)
func ensureLayout(forCharacterRange: NSRange)
func ensureLayout(forGlyphRange: NSRange)
func ensureLayout(for: NSTextContainer)

根据OP的评论,在.ensureLayout中调用viewDidLayoutSubviews()解决了该问题。

相关问题