对于给定的 NSRange ,我想在 CGRect 中找到一个 UILabel ,它对应于那个 NSRange 的字形。例如,我想在句子“The quick brown fox jumps over the lazy dog”中找到包含单词“dog”的 CGRect

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

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

我想在我的 UILabel 子类上编写的方法看起来像这样:

 - (CGRect)rectForSubstringWithRange:(NSRange)range;

详情,有兴趣的可以看看:

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

到目前为止我为尝试解决问题所做的工作:
  • 我希望在 iOS 7 中,会有一些 Text Kit 可以解决这个问题,但我在 Text Kit 中看到的大多数例子都集中在 UITextViewUITextField 上,而不是 231343141 ,
  • 我在这里看到了另一个关于堆栈溢出的问题,它有望解决这个问题,但接受的答案已经超过两年了,并且代码在属性文本上表现不佳。

  • 我敢打赌,正确答案涉及以下之一:
  • 使用标准的Text Kit方法在一行代码中解决这个问题。我敢打赌它会涉及 UILabelNSLayoutManager
  • 编写一个复杂的方法,将 UILabel 分成几行,并在一行中查找字形的矩形,可能使用 Core Text 方法。我目前最好的选择是拆开 @mattt's 优秀的 TTTAttributedLabel ,它有一个方法可以在某个点找到一个字形 - 如果我反转它,并找到一个字形的点,那可能会起作用。


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

    最佳答案

    在代码中 Joshua's answer 之后,我想出了以下似乎运行良好的方法:

    - (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];
    }
    

    关于ios - 如何在 UILabel 中找到文本子字符串的 CGRect?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/19417776/

    10-14 21:58