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

Does NSAttributedString's enumerateAttribute method's block pass character ranges or glyph ranges?

tl;dr:如果我调用 NSAttributedStringenumerateAttribute:inRange:options:usingBlock: 方法,块的 range 参数是否传递字形范围或字符范围?

我的应用程序中有一个文本视图需要像 Notes.app 一样运行,因为当它不处于编辑模式时,它应该显示 hyperlinks(并且它们应该是可点击的),它应该在点击时进入编辑模式。 UITextView 在可编辑时不显示 hyperlinks,但如果它不可编辑,则它不会自行获得焦点。在 iOS 11 之前,这可以通过在文本视图上使用 UITapGestureRecognizer 来触发编辑来解决,但似乎有些东西(可能是拖放?)改变了手势识别器与 UITextView 的工作方式(雷达://33009324)。

我的新改进解决方案是一个自定义 UIGestureRecognizer,如果它在 hyperlink 上看到 不是 的点击,它就会触发,并使所有文本视图上的其他识别器要求它在触发前失败。这是通过处理触摸、获取它们在文本视图中的位置、获取 character index for that point、在文本视图的 textStorage 中枚举 NSLinkAttributeName 并检查我的字符索引是否与任何重叠来实现的hyperlinks 我回来了。如果是这样,则用户点击了 link,并且此识别器失败。

但是,如果抽头的字符索引确实与 link 相交,我需要确保抽头确实与 link 的矩形相交,因为这可能是link 是文本视图内容中的最后一件事,触摸实际上是在最后一行文本的下方。我可以通过获取 link 范围的矩形并检查它是否与我的触摸点相交来做到这一点。我可以先用boundingRectForGlyphRange:inTextContainer: for this, but this leads to my question: is the range I have for the link a character range or a glyph range? Do I need to convert it via glyphRangeForCharacterRange:actualGlyphRange:吗?

它returns一个字符范围。 NSAttributedString 对字形一无所知。在执行布局之前,不会将字符转换为字形,并且 NSAttributedString 不包括布局信息。例如,NSAttributedString 不知道它会被绘制到多宽的区域,没有它,你无法知道换行符在哪里,没有它你无法决定在哪里放置连字.

NSAttributedString 对字形一无所知,是的,如果您需要知道字形在 TextKit 堆栈(例如 UITextView 的堆栈)中的位置,您可以让布局管理器为您转换。