UITextView实现点击富文本响应事件
前因:开发中常常会遇到点击富文本链接跳转的情况,最常碰到的是在注册的时候会有同意各种协议的文本,点击会跳转显示对应协议。
通过UITextView添加带有超链接的富文本,就可以在delegate的
- (BOOL)textView:(UITextView *)textView shouldInteractWithURL:(NSURL *)URL inRange:(NSRange)characterRange interaction:(UITextItemInteraction)interaction {
NSLog(@"%@", URL);
return YES;
}
监听到点击链接的事件。
这样就不用写两个button或者其他方式实现点击效果,方便快捷。
具体设置如下:
NSMutableAttributedString *mAttr = [[NSMutableAttributedString alloc] initWithString:@"点击“注册”即表示您同意"];
NSAttributedString *registPolicyAttr = [[NSAttributedString alloc] initWithString:@"《用户注册服务协议》" attributes:@{
NSForegroundColorAttributeName: [UIColor colorWithRed:78/255.0 green:187/255.0 blue:192/255.0 alpha:1.0],
NSLinkAttributeName: @"www.baidu.com"
}];
NSAttributedString *privacyPolicyAttr = [[NSAttributedString alloc] initWithString:@"&《用户隐私协议》" attributes:@{
NSForegroundColorAttributeName: [UIColor colorWithRed:78/255.0 green:187/255.0 blue:192/255.0 alpha:1.0],
NSLinkAttributeName: @"www.google.com"
}];
[mAttr appendAttributedString:registPolicyAttr];
[mAttr appendAttributedString:privacyPolicyAttr];
textView.attributedText = mAttr.copy;
textView.delegate = self;
textView.scrollEnabled = NO;
textView.editable = NO;
但是还有一些细节的地方需要调整一下。
UITextView的超链接一直是蓝色
这是因为UITextView自带了样式,我们只需要在设置textView.attributedText
之前,把样式清空就行。
textView.linkTextAttributes = @{};
点击超链接的时候,会有底色为灰色的高亮显示
这种系统默认的实现,好像没有找到可以修改的地方(如果有希望大家在评论区告诉我)。只能用别的办法解决,幸好UITextView给我们提供了一个方法,可以根据点击的点获取最近区域的富文本状态,通过判断获取到的富文本是否包含超链接,来响应超链接事件。
- (void)handleTap:(UITapGestureRecognizer *)tap {
UITextView *textView = (UITextView *)tap.view;
CGPoint tapLocation = [tap locationInView:textView];
UITextPosition *position = [textView closestPositionToPoint:tapLocation];
NSDictionary *attr = [textView textStylingAtPosition:position inDirection:UITextStorageDirectionForward];
if ([attr.allKeys containsObject:NSLinkAttributeName]) {
NSLog(@"%@", attr[NSLinkAttributeName]);
}
}
禁用文本选择和复制粘贴
为了让实现效果看起来更像点击了两个按钮,要取消掉UITextView的文本选择和复制粘贴功能。
- (BOOL)textViewShouldBeginEditing:(UITextView *)textView {
return NO;
}
返回NO即可。
2、例子:
- (void)viewDidLoad {
_agreementTextView = [[UITextView alloc] init];
_agreementTextView.text = @"我已阅读并同意《俄语阅读用户服务协议》";
_agreementTextView.backgroundColor = [UIColor yellowColor];
_agreementTextView.textColor = RGBA(142, 142, 142, 1);
_agreementTextView.textAlignment = NSTextAlignmentCenter;
_agreementTextView.textContainerInset = UIEdgeInsetsMake(0, 0, 0, 0);
_agreementTextView.font = [UIFont systemFontOfSize:[UIScreen mainScreen].bounds.size.width/375*11 weight:UIFontWeightRegular];
_agreementTextView.showsVerticalScrollIndicator = NO;
_agreementTextView.scrollEnabled = NO;
_agreementTextView.editable = NO;
self.agreementTextView.delegate = self;
[self.view addSubview:self.agreementTextView];
[self.agreementTextView makeConstraints:^(MASConstraintMaker *make) {
make.centerX.equalTo(self.view);
make.top.mas_equalTo(self.loginQuickBut.mas_bottom).offset([UIScreen mainScreen].bounds.size.width/375*28);
make.width.mas_equalTo([UIScreen mainScreen].bounds.size.width/375*235);
make.height.mas_equalTo([UIScreen mainScreen].bounds.size.width/375*13);
}];
[self agreementSetupHanle];
}
- (void)agreementSetupHanle {
NSString *agreementMessage = self.agreementTextView.text;
NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc]initWithString:agreementMessage];
[attributedString addAttribute:NSLinkAttributeName
value:@"2"
range:[[attributedString string] rangeOfString:@"《俄语阅读用户服务协议》"]];
[attributedString addAttribute:NSFontAttributeName value:[UIFont systemFontOfSize:[UIScreen mainScreen].bounds.size.width/375*11] range:[[attributedString string] rangeOfString:agreementMessage]];
[attributedString addAttribute:NSForegroundColorAttributeName value:RGBA(142, 142, 142, 1) range:[[attributedString string] rangeOfString:agreementMessage]];
self.agreementTextView.linkTextAttributes = @{ NSForegroundColorAttributeName: [UIColor colorWithRed:75.0/255.0 green:168.0/255.0 blue:161.0/255.0 alpha:1],
NSUnderlineColorAttributeName: [UIColor clearColor],
NSUnderlineStyleAttributeName: @(NSUnderlineStyleSingle)};
// 设置间距
NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init];
paragraphStyle.lineSpacing = 5;// 字体的行间距
[attributedString addAttribute:NSParagraphStyleAttributeName value:paragraphStyle range:[[attributedString string] rangeOfString:agreementMessage]];
self.agreementTextView.attributedText = attributedString;
}
- (BOOL)textView:(UITextView *)textView shouldInteractWithURL:(NSURL *)URL inRange:(NSRange)characterRange interaction:(UITextItemInteraction)interaction {
if ([URL.absoluteString isEqualToString:@"2"]) {
CheckUserAgreementCTRL *agreementVC = [[CheckUserAgreementCTRL alloc] init];
agreementVC.originMark = 2;
[self.navigationController pushViewController:agreementVC animated:YES];
}
return YES;
}
- (BOOL)textViewShouldBeginEditing:(UITextView *)textView {
// 禁用文本复制、粘贴
return NO;
}