UITextView内の特定文字を文字装飾してタップイベントを追加する


概要

以下のような画面で、名前(wrbss)にだけタップイベントを追加したい場合にとった方法です。文字列はUITextViewで表示しています。

やり方

NSAttributedStringにリンクを仕込んで、リンクタップイベントを上書きすることで実装しました。

対象クラスにUITextViewDelegateを実装

SampleViewController.h
@interface SampleViewController : UIViewController<UITextViewDelegate>

@property (weak, nonatomic) IBOutlet UITextView *comment;

@end

NSAttributedStringで表示文字列を生成

文字列をNSAttributedStringで生成して、タップイベントを付けたい箇所にNSLinkAttributeNameを設定

SampleViewController.m
    // タップ可能文字列
    NSMutableAttributedString *tappableText = [[NSMutableAttributedString alloc] initWithString:@"wrbss" attributes: @{
        NSForegroundColorAttributeName:[UIColor lightGrayColor],
        NSFontAttributeName:[UIFont systemFontOfSize:13.5f],
        NSUnderlineColorAttributeName: [UIColor clearColor],
        NSUnderlineStyleAttributeName: @(NSUnderlineStyleNone)
    }];

    // 識別するために適当なURLスキームを設定
    [tappableText addAttribute:NSLinkAttributeName value:@"sample://user" range:NSMakeRange(0, tappableText.length)];

    // 非タップ文字列
    NSAttributedString *normalText = [[NSAttributedString alloc] initWithString:postRecord.comment attributes:@{
        NSForegroundColorAttributeName:[UIColor blackColor],
        NSFontAttributeName:[UIFont systemFontOfSize:13.0f]
    }];

    NSMutableAttributedString *comment = [NSMutableAttributedString new];
    [comment appendAttributedString:tappableText];
    [comment appendAttributedString:normalText];

    _comment.attributedText = comment;
    _comment.linkTextAttributes = @{NSForegroundColorAttributeName:[UIColor lightGrayColor]};
    // リンクタップイベントをoverrideするためにdelegate
    _comment.delegate = self;

URLタップ時のイベントをoverrideして、上記で設定したURLの場合に実行したい処理を書く

- (BOOL)textView:(UITextView *)textView shouldInteractWithURL:(NSURL *)URL inRange:(NSRange)characterRange
{
    if ([[URL absoluteString] isEqualToString:@"sample://user"]) {
        // ここにタップ時の処理を書く
    }

    return NO;
}

参考