项目登录页面需要添加产品协议和隐私政策,想到的方案就是使用富文本添加超链接点击事件
- (void)configContentWithArray:(NSArray *)array{
NSMutableString *str = [NSMutableString string];
for (NSInteger i = 0; i < array.count; i++) {
NSDictionary *dic = array[i];
[str appendString:dic[@"str"]];
}
NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:str];
for (NSInteger i = 0; i < array.count; i++) {
NSDictionary *dic = array[i];
[attributedString addAttributes:@{NSFontAttributeName : dic[@"font"],NSForegroundColorAttributeName : dic[@"color"]} range:[[attributedString string] rangeOfString:dic[@"str"]]];
if ([dic[@"click"] boolValue]) {
[attributedString addAttribute:NSLinkAttributeName
value:[NSString stringWithFormat:@"click%@://",@(i)]
range:[[attributedString string] rangeOfString:dic[@"str"]]];
[attributedString addAttribute:NSForegroundColorAttributeName
value:dic[@"color"]
range:[[attributedString string] rangeOfString:dic[@"str"]]];
}
}
NSMutableParagraphStyle *ornamentParagraph = [[NSParagraphStyle defaultParagraphStyle] mutableCopy];
//设置text文字居中
ornamentParagraph.alignment = NSTextAlignmentCenter;
[attributedString addAttribute:NSParagraphStyleAttributeName value:ornamentParagraph range:[[attributedString string] rangeOfString:attributedString.string]];
self.content = attributedString;
self.textView.attributedText = self.content;
}
但是在测试的过程中出现了低版本点击无效果的现象;发现该方法- (BOOL)textView:(UITextView *)textView shouldInteractWithURL:(NSURL *)URL inRange:(NSRange)characterRange interaction:(UITextItemInteraction)interaction API_AVAILABLE(ios(10.0))在iOS10以后才有用,所以需要想办法实现iOS10以下版本的点击效果
-
(BOOL)textView:(UITextView *)textView shouldInteractWithURL:(NSURL *)URL inRange:(NSRange)characterRange interaction:(UITextItemInteraction)interaction API_AVAILABLE(ios(10.0)){
if ([[URL scheme] containsString:@"click"]) {
NSAttributedString *abStr = [textView.attributedText attributedSubstringFromRange:characterRange];
if (self.eventBlock) {
self.eventBlock(abStr.string);
}return NO;
}
return YES;
}
替代方法是- (BOOL)textView:(UITextView)textView shouldInteractWithURL:(NSURL)URL inRange:(NSRange)characterRange,但是该方法的操作和iOS10的方法有区别,这个需要长按才会有反应;操作体验有差别,效果不好,所以添加手势辅助操作实现点按功能
UITapGestureRecognizer *tapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(addGestureRecognizer:)];
[self.textView addGestureRecognizer:tapRecognizer]
//该方法支持(7_0, 10_0),长按才有反应,点击无效果,所以添加手势辅助操作实现点按功能 -
(BOOL)textView:(UITextView)textView shouldInteractWithURL:(NSURL)URL inRange:(NSRange)characterRange{
if (([URL isKindOfClass:[NSString class]] && [(NSString *)URL containsString:@"click"]) || [[URL scheme] containsString:@"click"]) {
NSAttributedString *abStr = [textView.attributedText attributedSubstringFromRange:characterRange];
if (self.eventBlock) {
self.eventBlock(abStr.string);
}return NO;
}
return YES;
} -
(void)addGestureRecognizer:(UIGestureRecognizer*)gestureRecognizer{
if ([gestureRecognizer isKindOfClass:[UITapGestureRecognizer class]])
{
CGPoint tapLocation = [gestureRecognizer locationInView:self.textView];
UITextPosition *textPosition = [self.textView closestPositionToPoint:tapLocation];
NSDictionary *attributes = [self.textView textStylingAtPosition:textPosition inDirection:UITextStorageDirectionBackward];
NSURL *url = attributes[NSLinkAttributeName];
if(url) {
NSRange range = [self.textView.text rangeOfString:@"《产品协议》"];
if (([url isKindOfClass:[NSString class]] && [(NSString *)url containsString:@"click1"]) || (([url isKindOfClass:[NSURL class]] && [[url scheme] containsString:@"click1"]))) {
range = [self.textView.text rangeOfString:@"《产品协议》"];
} else if(([url isKindOfClass:[NSString class]] && [(NSString *)url containsString:@"click3"]) || (([url isKindOfClass:[NSURL class]] && [[url scheme] containsString:@"click3"]))){
range = [self.textView.text rangeOfString:@"《隐私保护指引》"];
}if([self conformsToProtocol:@protocol(UITextViewDelegate)] && [self respondsToSelector:@selector(textView:shouldInteractWithURL:inRange:)]) { [self textView:self.textView shouldInteractWithURL:url inRange:range]; } }
}
[super addGestureRecognizer:gestureRecognizer];
}
以上代码就可以完美的兼容不同版本的点击效果,做个记录