2017-08-28 315 views
1

tl; dr:如果我打电话给NSAttributedStringenumerateAttribute:inRange:options:usingBlock:方法,该块的参数range是否会传递字形范围或字符范围?NSAttributedString的enumerateAttribute方法的块是否传递字符范围或字形范围?

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

我的新的和改进的解决方案是一个自定义UIGestureRecognizer将触发,如果它看到一个水龙头是上的超链接,并就文中的所有其他识别器,要求它发射之前失败。这是通过处理触摸,在文本视图中获取它们的位置,获取character index for that point,在文本视图的textStorage中枚举NSLinkAttributeName,并检查我的字符索引是否与我返回的任何超链接重叠来实现的。如果是这样,那么用户点击一个链接,这个识别器失败。

但是,如果水龙头的角色索引与链接相交,我需要确保水龙头实际上与链接的矩形相交,因为这可能是该链接是文本视图内容中的最后一件事情,触摸实际上低于文本的最后一行。我可以通过获取链接范围的矩形并检查它是否与我的触点相交来做到这一点。我可以使用boundingRectForGlyphRange:inTextContainer:这个,但是这导致我的问题:我的链接范围是字符范围还是字形范围?我是否需要先通过glyphRangeForCharacterRange:actualGlyphRange:进行转换?

+1

感谢您的提问;这是一个非常有趣的用例,我仍然困惑着是否有更好的方法来解决这个问题(但你可能已经做了最好的工作...... UITextView是非常灵活的IMO)。 –

回答

2

它返回一个字符范围。 NSAttributedString直接不了解关于字形的任何信息。只有在执行布局之前,才能将字符转换为字形,并且NSAttributedString不包含布局信息。例如,一个NSAttributedString不知道它将被拉入的区域有多宽,如果没有该区域,则无法知道换行符会在哪里出现,如果没有,则无法决定将连字符放在哪里。

1

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