1. ホーム
  2. ios

UILabelのテキストの部分文字列のCGRectを見つけるにはどうしたらいいですか?

2023-08-06 06:44:40

質問

与えられた NSRange を見つけたい。 CGRect の中に UILabel のグリフに対応する、その NSRange . 例えば、私が見つけたいのは CGRect という文の中にある、quot;dog" という単語を含む を見つけたいのです。

トリックは UILabel が複数の行を持ち、テキストが本当に attributedText であるため、文字列の正確な位置を見つけるのは少し難しいです。

に書きたいメソッドは、私の場合 UILabel サブクラスに書きたいメソッドは次のようになります。

 - (CGRect)rectForSubstringWithRange:(NSRange)range;


詳細、興味のある方のために。

私の目標は、次のことができるようになることです。 UILabel の外観と位置を正確に再現した新しい UILabel を作成し、それをアニメートできるようにすることです。 残りの部分は理解できましたが、特にこの手順が今のところ私を妨げています。

これまで問題を解決するためにやったこと。

  • iOS 7 では、この問題を解決する Text Kit があるだろうと期待していましたが、私が見た Text Kit の例のほとんどは、この問題を解決するために UITextViewUITextField よりも、むしろ UILabel .
  • 私は、この問題を解決することを約束する Stack Overflow の別の質問をここで見ましたが、受け入れられた回答は 2 年以上前のもので、コードは属性付きのテキストでうまく実行されません。

これに対する正しい答えは、次のいずれかを含んでいることに賭けます。

  • Text Kit の標準的なメソッドを使用して、1 行のコードでこの問題を解決する。きっと、それには NSLayoutManagertextContainerForGlyphAtIndex:effectiveRange
  • UILabel を行に分割し、行内のグリフの rect を見つける複雑なメソッドを書くことで、おそらく Core Text のメソッドを使用します。私の現在の最善の策は @mattt の 優れた TTTAttributedLabel には、ある点でのグリフを見つけるメソッドがあります。これを反転して、グリフの点を見つければ、うまくいくかもしれません。

更新: この問題を解決するためにこれまで試した 3 つのことを github gist にまとめました。 https://gist.github.com/bryanjclark/7036101

どのように解決するのですか?

次のように ジョシュアさんの回答 をコード化すると、次のようになり、うまくいくようです。

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