美文网首页
UITextView富文本超链接点击

UITextView富文本超链接点击

作者: 黑暗森林的歌者 | 来源:发表于2018-09-03 17:30 被阅读240次

UITextView富文本超链接点击

UITextView显示富文本的时候,如果富文本中有超链接,有时候需要单独处理这个链接的点击。

可以继承UITextView重写hitTest方法,拦截点击的内容,然后进行跳转。

首先重写canPerformAction方法,取消UITextView的一些弹出菜单的响应。

- (BOOL)canPerformAction:(SEL)action withSender:(id)sender {
    //一旦双击,里面禁用。取消第一响应者,设置不可交互。
    [self resignFirstResponder];
//    self.userInteractionEnabled = NO;
    if ([UIMenuController sharedMenuController]) {
        [UIMenuController sharedMenuController].menuVisible = NO;
    }
    return NO;
}

重写hitTest方法,拦截点击的字符串

- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
    
    // 获取点击的字母的位置
    NSInteger characterIndex = [self.layoutManager characterIndexForPoint:point inTextContainer:self.textContainer fractionOfDistanceBetweenInsertionPoints:NULL];
    
    // 获取单词的范围。range 由起始位置和长度构成。
    NSRange range = [self getWordRange:characterIndex];
    
    NSAttributedString *clickedString = [self.attributedText attributedSubstringFromRange:range];
    __block BOOL isLink = NO;
    [clickedString enumerateAttributesInRange:NSMakeRange(0, clickedString.length) options:1 usingBlock:^(NSDictionary<NSAttributedStringKey,id> * _Nonnull attrs, NSRange range, BOOL * _Nonnull stop) {
        [attrs enumerateKeysAndObjectsUsingBlock:^(NSAttributedStringKey  _Nonnull key, id  _Nonnull obj, BOOL * _Nonnull stop) {
            if ([key isEqualToString:@"NSLink"]) {
                if (((NSURL *)obj).absoluteString.length > 0) {

                    isLink = YES;
                    *stop = YES;
                }
            }
        }];
    }];
    if (isLink) {
        return self;
    }
    return self.superview;
}

过滤点击的字符

- (NSRange)getWordRange:(NSInteger)characterIndex {
    NSInteger left = characterIndex - 1;
    NSInteger right = characterIndex + 1;
    NSInteger length = 0;
    NSString *string = self.attributedText.string;
    
    // 往左遍历直到空格
    while (left >=0) {
        NSString *s=[string substringWithRange:NSMakeRange(left, 1)];
        
        if ([self isLetter:s]) {
            left --;
        } else {
            break;
        }
    }
    
    // 往右遍历直到空格
    while (right < self.text.length) {
        NSString *s=[string substringWithRange:NSMakeRange(right, 1)];
        
        if ([self isLetter:s]) {
            right ++;
        } else {
            break;
        }
    }
    
    // 此时 left 和 right 都指向空格
    left ++;
    right --;
    length = right - left + 1;
    NSRange range = NSMakeRange(left, length);
    
    return range;
}

判断是否字母

- (BOOL)isLetter:(NSString *)str {
    char letter = [str characterAtIndex:0];

    if ((letter >= 'a' && letter <='z') || (letter >= 'A' && letter <= 'Z')) {

        return YES;
    }

    return NO;
}

因为我们的需求是做一个评论内容列表,UITextView是放在UITableviewCell中,如果是超链接,就会用Safari打开,如果不是,对cell的点击,依旧是cell响应。

相关文章

网友评论

      本文标题:UITextView富文本超链接点击

      本文链接:https://www.haomeiwen.com/subject/dyjiwftx.html