10

这是 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

4 回答 4

8

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

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

现在您将不得不在框架中寻找相关的文本块。用获取CTLineRefs的数组CTFrameGetLines()

遍历数组,测试触摸是否在该行上,方法是检查它是否在CTLineGetImageBounds(). 如果是,现在查看行中的字形运行。

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

于 2010-09-26T03:56:48.677 回答
3

您需要通过 CTLine 找到 Y,通过 CTRun 宽度和高度找到 X,您可以通过单词和字体本身获得。生病附上我的项目链接,它的代码非常简单,但您可以重新编辑以满足您的需求。希望它有助于欢呼,如果你改进一般逻辑请让我知道 thx。 文本视图项目

于 2010-11-26T13:00:48.340 回答
2

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

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

总的来说,在调整后的代码中: y 坐标、宽度和高度是使用 CTRunGetImageBounds计算的。并且 x 坐标是使用CTRunGetTypographicBounds计算的。

于 2011-08-03T05:00:27.770 回答
0

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

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

如果您决定使用它并发现问题,请不要犹豫在 github 上发布问题!

于 2010-12-25T17:17:46.420 回答