2

我有一个 UITextView,我正在向其中添加一些自定义 UI。此自定义 UI 的布局基于 UITextView 中文本的位置。

firstRectForRange在 UITextView 上使用方法(来自 UITextInput)。该方法返回 textView 中指定文本范围的框架。

但是,它在设置属性文本后无法正常工作。在返回预期值之前需要最少的时间。这段时间很可能是直到带有更新文本的第一帧被渲染并显示在屏幕上的时间。

我目前正在将布置自定义 UI 的代码包装到一个dispatch_async(dispatch_get_main_queue(), ...)块中,这会将其执行延迟到帧渲染之后(大约 9 毫秒)。

UITextView 在设置属性字符串和在屏幕上显示下一帧之间做了什么?有没有更好的地方/方法调用让我挂钩?
我有什么办法可以强制同步运行该操作?

我尝试过调用的事情:(
在设置属性文本之后;在调用 firstRectForRange 之前)

  • 调用setNeedsLayoutlayoutIfNeeded之前firstRectForRange
  • 打电话drawViewHierarchyInRect(self.bounds, afterScreenUpdates: true)
4

1 回答 1

0

您是否尝试从后台线程设置属性文本?我猜这就是问题所在。所有界面更改都应该发生在主线程上。从个人经验来看,从后台线程更改内容偶尔会起作用,通常会更慢,甚至更多时候根本不起作用。

如果是这种情况,那dispatch_async正是您想要做的。它使在后台处理数据变得非常容易,然后快速跳到主线程进行渲染。如果您想在设置字符串并找到之后进行更多处理,firstRectForRange您可以使用 adispatch_sync让您的后台线程等待渲染,或者在渲染后分派回另一个线程。

至于 UITextView 在渲染属性字符串时做了什么,我真的不确定,但我猜这个轻微的延迟来自于系统弄清楚属性字符串应该是什么样子,以及它将如何渲染。为了进一步了解,您可能需要深入研究 CoreText,因为幕后发生了很多事情。

编辑:如果您在主线程上,那么我认为您无能为力。使用dispatch_after可能比使用 dispatch_async 稍微干净一些。

又一想。你试过打电话setNeedsDisplay吗?这通常会告诉视图重绘自己。

于 2015-08-27T15:21:15.627 回答