UITextView 设置属性后做啥?

Posted

技术标签:

【中文标题】UITextView 设置属性后做啥?【英文标题】:What does a UITextView do after setting attributedText?UITextView 设置属性后做什么? 【发布时间】:2015-08-27 15:02:49 【问题描述】:

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

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

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

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

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

我尝试调用的内容:(设置属性文本后;调用 firstRectForRange 之前)

firstRectForRange 之前调用setNeedsLayoutlayoutIfNeeded。 致电drawViewHierarchyInRect(self.bounds, afterScreenUpdates: true)

【问题讨论】:

【参考方案1】:

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

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

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

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

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

【讨论】:

不,一切都发生在主线程上。我只是使用 dispatch_async 将执行延迟最短时间。 嘿@TimBodeit,我用另外几个案例更新了我的答案。希望这会有所帮助。

以上是关于UITextView 设置属性后做啥?的主要内容,如果未能解决你的问题,请参考以下文章

无法更改 UIText 视图的字体(使用 Web 服务时)

在多个 UITextView 中显示长文本

UITextView textContainer排除路径在视图控制器的中间时不起作用

在 UITextView 上以编程方式禁用 iOS8 Quicktype 键盘

如何在 UITextView 中实现滚动功能?

UIPopOver、UITextView 和自动调整大小