前言
总是会有“我已经阅读并同意了《各种协议》” 这样的东西,一般都是高亮字体,点击还能跳转。。 我从来没用过button去拼凑链接
代码地址 https://github.com/gityuency/ObjectiveCTools
【类名:TextViewViewController】
效果图:
上一次写的这个文本框文字链接有些小问题,在长按、点击之后长按、双击、等手势操作的时候,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
结语:
感谢各位给我写的评论,因为我很长一段时间没有电脑,也没法摸代码。这波我把能改的问题都改了一下。