如何在UILabel中为文本的子字符串找到CGRect?

对于给定的NSRange,我想找到一个CGRect在UILabel对应的的字形NSRange。例如,我想CGRect在句子“快速的棕色狐狸跳过懒狗”中找到包含“狗”一词的。


诀窍是,它UILabel具有多行,并且文本实际上是attributedText,因此要找到字符串的确切位置有点困难。


我想在UILabel子类上编写的方法如下所示:


 - (CGRect)rectForSubstringWithRange:(NSRange)range;

细节,对于那些感兴趣的人:


我的目标是能够创建具有UILabel确切外观和位置的新UILabel,然后可以对其进行动画处理。我已经弄清了其余的一切,但是尤其是这一步使我此刻退缩。


到目前为止,我为解决问题所做的工作:


我希望在iOS 7上有一些Text Kit可以解决此问题,但是我在Text Kit上看到的每个示例大多数都针对UITextView和UITextField,而不是UILabel。

我在这里看到了关于Stack Overflow的另一个问题,该问题有望解决该问题,但是公认的答案已经存在了两年多,并且代码在归因于文本的情况下表现不佳。

我敢打赌,对此的正确答案涉及以下之一:


使用标准的文本工具包方法在一行代码中解决此问题。我敢打赌这会涉及NSLayoutManager到textContainerForGlyphAtIndex:effectiveRange

编写一个复杂的方法,可以将UILabel分成几行,并可能使用Core Text方法在一行中找到一个字形的矩形。我目前最好的选择是分解@mattt出色的TTTAttributedLabel,该方法具有一种在某个点找到字形的方法-如果我将其反转,然后找到一个字形的点,则可能会起作用。

更新:这是一个github要点,其中包含我迄今为止为解决该问题而尝试过的三件事:https : //gist.github.com/bryanjclark/7036101


慕哥6287543
浏览 625回答 3
3回答

拉莫斯之舞

遵循约书亚在代码中的回答,我提出了以下似乎很好的方法:- (CGRect)boundingRectForCharacterRange:(NSRange)range{    NSTextStorage *textStorage = [[NSTextStorage alloc] initWithAttributedString:[self attributedText]];    NSLayoutManager *layoutManager = [[NSLayoutManager alloc] init];    [textStorage addLayoutManager:layoutManager];    NSTextContainer *textContainer = [[NSTextContainer alloc] initWithSize:[self bounds].size];    textContainer.lineFragmentPadding = 0;    [layoutManager addTextContainer:textContainer];    NSRange glyphRange;    // Convert the range for glyphs.    [layoutManager characterRangeForGlyphRange:range actualGlyphRange:&glyphRange];    return [layoutManager boundingRectForGlyphRange:glyphRange inTextContainer:textContainer];}

RISEBY

我的建议是利用文本工具包。不幸的是,我们无法UILabel使用a的布局管理器,但是可以创建它的副本并使用它来获取范围的rect。我的建议是创建一个NSTextStorage包含与标签完全相同的属性文本的对象。接下来,创建一个NSLayoutManager并将其添加到文本存储对象中。最后,创建一个NSTextContainer与标签大小相同的,然后将其添加到布局管理器中。现在,文本存储与标签具有相同的文本,文本容器与标签具有相同的大小,因此我们应该能够使用来向我们创建的布局管理器询问我们的范围boundingRectForGlyphRange:inTextContainer:。确保首先glyphRangeForCharacterRange:actualCharacterRange:在布局管理器对象上使用,将字符范围转换为字形范围。一切顺利,应该使您可以确定 CGRect标签内指定的范围的边界。我尚未对此进行测试,但这将是我的方法,并且通过模仿UILabel自身的工作方式,应该有很大的成功机会。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

iOS