の場合UILabel
、タッチイベントから受け取った特定のポイントにある文字インデックスを見つけたいと思います。Text Kit を使用して、iOS 7 でこの問題を解決したいと考えています。
UILabel はその へのアクセスを提供しないため、次のような の構成NSLayoutManager
に基づいて独自のものを作成しました。UILabel
- (void)textTapped:(UITapGestureRecognizer *)recognizer
{
if (recognizer.state == UIGestureRecognizerStateEnded) {
CGPoint location = [recognizer locationInView:self];
NSTextStorage *textStorage = [[NSTextStorage alloc] initWithAttributedString:self.attributedText];
NSLayoutManager *layoutManager = [[NSLayoutManager alloc] init];
[textStorage addLayoutManager:layoutManager];
NSTextContainer *textContainer = [[NSTextContainer alloc] initWithSize:self.bounds.size];
[layoutManager addTextContainer:textContainer];
textContainer.maximumNumberOfLines = self.numberOfLines;
textContainer.lineBreakMode = self.lineBreakMode;
NSUInteger characterIndex = [layoutManager characterIndexForPoint:location
inTextContainer:textContainer
fractionOfDistanceBetweenInsertionPoints:NULL];
if (characterIndex < textStorage.length) {
NSRange range = NSMakeRange(characterIndex, 1);
NSString *value = [self.text substringWithRange:range];
NSLog(@"%@, %zd, %zd", value, range.location, range.length);
}
}
}
上記のコードは、呼び出すように構成されたUILabel
サブクラス( Gist ) にあります。UITapGestureRecognizer
textTapped:
結果の文字インデックスは理にかなっていますが (左から右にタップすると増加します)、正しくありません (ラベルの幅の約半分で最後の文字に到達します)。フォント サイズまたはテキスト コンテナ サイズが適切に設定されていないようですが、問題が見つかりません。
UILabel
を使用する代わりに、自分のクラスを のサブクラスにしたいと本当に思っていUITextView
ます。この問題を解決した人はいUILabel
ますか?
更新:私はこの質問に DTS チケットを費やしました。Apple のエンジニアは、次のコード スニペットのように、独自のレイアウト マネージャーを使用する実装で をオーバーライドすることを推奨しUILabel
ましdrawTextInRect:
た。
- (void)drawTextInRect:(CGRect)rect
{
[yourLayoutManager drawGlyphsForGlyphRange:NSMakeRange(0, yourTextStorage.length) atPoint:CGPointMake(0, 0)];
}
自分のレイアウト マネージャーをラベルの設定と同期させるのは大変な作業になると思いUITextView
ますUILabel
。
更新 2:結局使用することUITextView
にしました。このすべての目的は、テキストに埋め込まれたリンクのタップを検出することでした。を使用しようとしましNSLinkAttributeName
たが、このセットアップでは、リンクをすばやくタップしたときにデリゲート コールバックがトリガーされませんでした。代わりに、一定時間リンクを押さなければならず、非常に面倒です。そこで、この問題のないCCHLinkTextViewを作成しました。