iPhone CoreText:查找子字符串的像素坐标

时间:2010-09-26 00:41:20

标签: iphone ios4 substring nsattributedstring core-text

以下是twitter应用程序的屏幕截图供参考:http://screencast.com/t/YmFmYmI4M

我想要做的是在NSAttributedString中的子字符串顶部放置一个浮动弹出窗口,该字符串可以跨越多行。 NSAttributedString是项目的要求。

在提供的屏幕截图中,您可以看到链接是背景突出显示的,因此它让我相信他们正在使用CoreText和NSAttributedStrings。我还发现了一个名为CTRunRef(http://developer.apple.com/library/ios/#documentation/Carbon/Reference/CTRunRef/Reference/reference.html)的东西看起来很有希望,但我在概念上无法将它们整合在一起。

简而言之,如果我在核心文本中有一个段落,当我点击一个单词时,如何找到该单词的边界框?

4 个答案:

答案 0 :(得分:8)

在属性字符串中设置一些不会影响显示的属性,但会将其作为单独的字形运行布局,然后使用CoreText来布局字符串

CTFramesetterRef framesetter = CTFramesetterCreateWithAttributedString(attrString);
CTFrameRef ctframe = CTFramesetterCreateFrame(framesetter, CFRangeMake(0, 0), path, NULL);

现在你必须通过框架搜索才能找到相关的文本块。使用CTLineRef获取CTFrameGetLines()的数组。

遍历数组,测试触摸是否在该行上,通过检查它是否在CTLineGetImageBounds()返回的矩形内。如果是,现在查看行中的字形。

同样,您可以使用CTRunRef获取CTLineGetGlyphRuns()个数组。检查点击是否在CTRunGetImageBounds()的字形运行范围内,如果是,您可以找到字形运行与CTRunGetStringIndices()对应的原始属性字符串中的索引范围。

答案 1 :(得分:3)

你需要通过CTLine找到Y和X通过CTRun宽度和高度找到你可以通过单词和字体本身获得。生病我的项目链接,它非常简单的代码,但你可以reedit以满足您的需求。如果你改善一般逻辑,希望它有助于欢呼请告诉我。 textViewProject

答案 2 :(得分:2)

George 给出的链接非常有帮助,让我得到了我想要的东西。但奇怪的事情发生了。它在 iOS SDK 4.0 中工作,但在 iOS SDK 5 中,链接的位置出现在视图的错误位置。

所以我不得不稍微调整一下代码。对于可触摸按钮的x坐标,我必须使用 CTRunGetTypographicBounds 而不是 CTRunGetImageBounds 函数。

总而言之,在调整过的代码中: 使用 CTRunGetImageBounds 计算y坐标,宽度和高度。 x坐标是使用 CTRunGetTypographicBounds 计算的。

答案 3 :(得分:0)

我一直在研究一个能够做到这一点的小型图书馆。您可以在此处找到它:https://github.com/pothibo/CMFramework

然而,这个库处于alpha阶段,需要优化并且缺少某些功能(行高是我想要添加的紧急功能之一)

如果您决定使用它并发现问题,请随时在github上发布问题!