NSAttributedString的enumerateAttribute方法的块是否传递字符范围或字形范围?

时间:2017-08-28 18:34:29

标签: ios uitextview nsattributedstring nslayoutmanager

tl; dr:如果我调用NSAttributedString的{​​{3}}方法,该块的range参数是否会传递字形范围或字符范围?

我的应用程序中有一个文本视图需要像Notes.app一样,因为当它不处于编辑模式时,它应该显示超链接(并且它们应该是可点击的),并且它应该进入编辑模式。 UITextView在可编辑时不显示超链接,但如果它不可编辑,那么它将无法专注于自己的点击。在iOS 11之前,这可以通过在文本视图上使用UITapGestureRecognizer来触发编辑来解决,但似乎某些事情(可能是通过拖放?)改变了手势识别器如何与UITextView一起使用(rdar:/ / 33009324)。

我的新改进解决方案是自定义UIGestureRecognizer,如果它在超链接上看到的点击,并且在文本视图上使所有其他识别器要求它,则会触发在开火前失败。这是通过处理触摸,在文本视图中获取其位置,获取enumerateAttribute:inRange:options:usingBlock:,在文本视图的NSLinkAttributeName中枚举textStorage,并检查我的角色索引是否与任何我得到的超链接。如果是这样,那么用户点击了一个链接,这个识别器就失败了。

但是,如果点击的字符索引与链接相交,我需要确保点击实际上与链接的rect相交,因为这可能是此链接是文本视图内容中的最后一个内容触摸实际上低于最后一行文字。我可以通过获取链接范围的矩形并检查它是否与我的触摸点相交来实现。我可以使用character index for that point来解决这个问题,但这会导致我的问题:我对链接的范围是字符范围还是字形范围?我是否需要先通过boundingRectForGlyphRange:inTextContainer:进行转换?

2 个答案:

答案 0 :(得分:2)

返回一个字符范围。 NSAttributedString对字形没有任何直接了解。将字符转换为字形不会发生,直到执行布局,NSAttributedString不包含布局信息。例如,NSAttributedString并不知道它将被绘制的区域有多宽,如果没有这个区域,您就无法知道换行符的位置,如果没有它,您可以“决定在哪里放置连字。

答案 1 :(得分:1)

NSAttributedString不知道任何字形,是的,如果您需要知道字形在TextKit堆栈中的位置,例如UITextView的字形,请让布局管理器为您进行转换。