iOS UITextView 文字链接点击事件

前言

总是会有“我已经阅读并同意了《各种协议》” 这样的东西,一般都是高亮字体,点击还能跳转。。 我从来没用过button去拼凑链接

代码地址 https://github.com/gityuency/ObjectiveCTools
【类名:TextViewViewController】

效果图:


文本链接.gif

上一次写的这个文本框文字链接有些小问题,在长按、点击之后长按、双击、等手势操作的时候,UITextView会有选中的样式出现,这次把刚刚那些问题都修复了。

代码:

第一步,继承UITextView,然后添加以下代码:

我在控制台里面打印出各种点击操作之后,出现的手势,但是这些手势貌似苹果没有提供出来给我们用,所以拿手势的名字来做判断,这招也还行,只是有iOS版本要求。
MyTextView.m


#import "MyTextView.h"

@implementation MyTextView

/// 重写手势响应的方法
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer {
    
    if (@available(iOS 11.0, *)) {
        
        //我们把需要的手势启用
        //其实我们只需要这个单选
        if ([gestureRecognizer.name isEqualToString:@"UITextInteractionNameSingleTap"]) {
            return YES;
        }
        //我们也需要这个链接点选
        if ([gestureRecognizer.name isEqualToString:@"UITextInteractionNameLinkTap"]) {
            return YES; //如果这里写成 NO, 那么在点击 TextView 上面自定义链接的时候, 就会失效
        }
        
        
        //我们把不需要的手势都禁用掉
        //禁用双击
        if ([gestureRecognizer.name isEqualToString:@"UITextInteractionNameDoubleTap"]) {
            return NO;
        }
        //禁用先点按之后长按
        if ([gestureRecognizer.name isEqualToString:@"UITextInteractionNameTapAndAHalf"]) {
            return NO;
        }
        //禁用长按 1
        if ([gestureRecognizer.name isEqualToString:@"_UIKeyboardTextSelectionGestureForcePress"]) {
            return NO;
        }
        //禁用长按 2
        if ([gestureRecognizer.name isEqualToString:@"UITextInteractionNameInteractiveLoupe"]) {
            return NO;
        }
        
    } else {
        // Fallback on earlier versions
    }
    return YES;
}


/// 注: 在 我重写了 gestureRecognizerShouldBegin: 方法后, 下面这个方法也可以不写, 因为手势被先禁用掉了, 所以响应事件就不会触发
/// 禁用掉 选择 多选 复制 剪切 粘贴 等各种东西
- (BOOL)canPerformAction:(SEL)action withSender:(id)sender {
    // 返回NO为禁用,YES为开启
    // 粘贴
    if (action == @selector(paste:)) {
        return NO;
    }
    // 剪切
    if (action == @selector(cut:)) {
        return NO;
    }
    // 复制
    if (action == @selector(copy:)) {
        return NO;
    }
    // 选择
    if (action == @selector(select:)) {
        return NO;
    }
    // 选中全部
    if (action == @selector(selectAll:)) {
        return NO;
    }
    // 删除
    if (action == @selector(delete:)) {
        return NO;
    }
    // 分享
    if (action == @selector(share)) {
        return NO;
    }
    return [super canPerformAction:action withSender:sender];
}

@end

第二步,写个控制器做测试用

TextViewViewController.m

#import "TextViewViewController.h"
#import "MyTextView.h"

@interface TextViewViewController () <UITextViewDelegate>

@property (nonatomic, strong) MyTextView *tview;

@end

@implementation TextViewViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    self.view.backgroundColor = UIColor.whiteColor;
    
    self.tview = [[MyTextView alloc] initWithFrame:CGRectMake(20, 150, [UIScreen mainScreen].bounds.size.width - 40, 300)];
    self.tview.backgroundColor = [[UIColor orangeColor] colorWithAlphaComponent:0.5];
    [self.view addSubview:self.tview];
    
    self.tview.delegate = self;
    self.tview.editable = NO;
    self.tview.scrollEnabled = NO;
    //self.vvv.selectable = NO; 这一句写了点击事件就失效
    
    NSString *aLink = @"《青米网络科技无限公司隐私协议》";
    NSString *bLink = @"《青米网络科技卖身协议》";
    NSString *link = [NSString stringWithFormat:@"我已经同意并且认真阅读了遵守%@%@",aLink,bLink];
    
    NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc]initWithString:link];
    
    //设置链接文本
    [attributedString addAttribute:NSLinkAttributeName
                             value:@"http://www.baidu.com"
                             range:[[attributedString string] rangeOfString:aLink]];
    
    [attributedString addAttribute:NSLinkAttributeName
                             value:@"http://www.163.com"
                             range:[[attributedString string] rangeOfString:bLink]];
    
    [attributedString addAttribute:NSFontAttributeName
                             value:[UIFont systemFontOfSize:24]
                             range:[[attributedString string] rangeOfString:link]];
    
    //设置链接样式
    self.tview.linkTextAttributes = @{
        NSForegroundColorAttributeName: [UIColor redColor],
        NSUnderlineColorAttributeName: [UIColor clearColor],
        NSUnderlineStyleAttributeName: @(NSUnderlineStyleSingle)
    };
    
    self.tview.attributedText = attributedString;
    
    
    NSLog(@"各种手势:\n %@", self.tview.gestureRecognizers);
}

#pragma mark - 实现链接代理
- (BOOL)textView:(UITextView *)textView shouldInteractWithURL:(NSURL *)URL inRange:(NSRange)characterRange {
    NSLog(@"可以判断一下链接, %@",URL);
    return YES;
}

- (BOOL)textView:(UITextView *)textView shouldInteractWithURL:(NSURL *)URL inRange:(NSRange)characterRange interaction:(UITextItemInteraction)interaction  API_AVAILABLE(ios(10.0)){
    NSLog(@"iOS 10+ %@",URL);
    return YES;
}

@end

结语:

感谢各位给我写的评论,因为我很长一段时间没有电脑,也没法摸代码。这波我把能改的问题都改了一下。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 173,237评论 25 708
  • 文语,繁花,慢慢。 我在百花齐放的春天慕你,在昼夜蝉鸣的长夏爱你,在银杏纷飞的金秋念你,在雪染大地的冬季等你。 你...
    语花慢阅读 274评论 7 0
  • 每到秋风来临,露水成霜时,树叶脱落了,群花萎缩了,唯有菊花迎风而立、傲霜怒放、千姿百态。
    0434欣玥阅读 239评论 0 4
  • “慈母手中線,游子身上衣”每每聽到女兒唱這首歌,不由讓我想起我的母親。在生活中母親是多麽慈祥的一角色,我的...
    兮敏阅读 233评论 0 0
  • 迷茫,是一个一直都很流行的词。比如说起青春的时候,都会说起那时候的迷茫,好像不迷茫就没有青春过一样。青春过后,为了...
    如柏的日记阅读 1,424评论 1 2