1. ホーム
  2. ios

[解決済み] iOSのUITextViewで属性付きテキストへのタップを検出する

2022-07-07 04:39:53

質問

私は UITextView を表示し NSAttributedString . この文字列には、タップできるようにしたい単語が含まれていて、タップされると呼び出されてアクションを実行できるようになります。私は、次のように理解しました。 UITextView は URL のタップを検出し、私のデリゲートをコールバックすることができますが、これらは URL ではありません。

iOS 7 と TextKit のパワーで、これは可能になるはずですが、例を見つけることができず、何から始めればよいのかわかりません。

文字列にカスタム属性を作成できるようになったということですが (まだやっていませんが)、おそらくこれがマジックワードの 1 つがタップされたかどうかを検出するのに役に立つのではないでしょうか。いずれにせよ、タップを遮断し、どの単語でタップが発生したかを検出する方法はまだわかっていません。

iOS 6 との互換性に注意してください。 ではない は必須ではありません。

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

私はちょうどもう少し他の人を助けたいと思いました。Shmidt の回答に従って、私が最初の質問で尋ねたとおりのことを行うことが可能です。

1) クリック可能な単語にカスタム属性を適用した属性付き文字列を作成します。

NSAttributedString* attributedString = [[NSAttributedString alloc] initWithString:@"a clickable word" attributes:@{ @"myCustomTag" : @(YES) }];
[paragraph appendAttributedString:attributedString];

2) その文字列を表示するUITextViewを作成し、そこにUITapGestureRecognizerを追加します。そして、タップを処理します。

- (void)textTapped:(UITapGestureRecognizer *)recognizer
{
    UITextView *textView = (UITextView *)recognizer.view;

    // Location of the tap in text-container coordinates

    NSLayoutManager *layoutManager = textView.layoutManager;
    CGPoint location = [recognizer locationInView:textView];
    location.x -= textView.textContainerInset.left;
    location.y -= textView.textContainerInset.top;

    // Find the character that's been tapped on

    NSUInteger characterIndex;
    characterIndex = [layoutManager characterIndexForPoint:location
                                           inTextContainer:textView.textContainer
                  fractionOfDistanceBetweenInsertionPoints:NULL];

    if (characterIndex < textView.textStorage.length) {

        NSRange range;
        id value = [textView.attributedText attribute:@"myCustomTag" atIndex:characterIndex effectiveRange:&range];

        // Handle as required...

        NSLog(@"%@, %d, %d", value, range.location, range.length);

    }
}

やり方がわかれば簡単!