这里不需要代码。我需要一些有关如何布局很长的多行字符串的所有字形的指导,以显示在启用滚动的UITextView中。了解一些背景信息的情况。
背景:我有一个很长的多字符串文本,需要在启用滚动的UITextView中显示。我创建了一个函数,该函数可以识别多行字符串中搜索字符串匹配项的CGRect
位置,然后将用户动画化为匹配项的CGRect
位置。这是通过将匹配文本的CGRect
传递到contentOffset
来实现的,该动画将滚动到该位置。传递给CGRect
的{{1}}是使用contentOffset
生成的,以确保准确性。换句话说,文本的layoutmanager
基于匹配字符串的字形的位置。
但是,如果匹配的搜索字符串的CGRect
垂直于UITextView CGRect
,则动画实际上会失败。没有任何滚动。好像滚动动画不知道要在哪里找到bounds.height
位置才能滚动到匹配的字符串。如果我先手动滚动到UITextView的最底部,然后将动画执行到匹配的搜索字符串的CGRect
位置,则可以纠正此问题。在这种情况下,UITextView似乎具有文本布局的完整图片,并且可以准确地找到匹配的搜索字符串CGRect
在多行字符串中的位置。
基于上述内容,对我来说很明显,UITextView不会一次布局多行字符串的所有字形。该视图可能以块的形式绘制字形,类似于表视图创建单元格的方式。在我看来,当我手动滚动经过视图的边界到内容垂直大小的最底部时,UITextView能够保留所有字形布局信息。
有没有可用的代码可以有效地布局UITextView的整个内容大小,即使这些字形远不在UITextView的垂直范围之内?看来我需要首先布置所有字形,以防止出现上述错误。
答案 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()
解决了该问题。