如何在文本中创建UITextView检测链接部分并仍然具有userInteractionDisabled?

Ati*_*ran 8 objective-c uitableview uitextview ios ios7

我有一个textView分层在tableView单元格上.我需要用户点击tableView行来打开一个viewController,但是如果textView有一个链接,那么它必须是可点击的,就是它,没有副本,选择等等.

如果我允许这样的用户交互:

textView.userInteractionEnabled=NO;
textView.dataDetectorTypes =UIDataDetectorTypeLink;
Run Code Online (Sandbox Code Playgroud)

didSelectRowAtIndexPath不叫,我明白为什么,但如何实现这一目标?

编辑:

我正在寻找的是能够专门识别链接并允许用户点击链接打开浏览器并禁用其他textView的交互.如上所述,整个行也应该是可点击的.

附加的是我的tableView单元格行的图像,它显示检测到链接并且也可以进行交互,但这会禁用didSelectRowAtIndexPathtextView区域内部.

在此输入图像描述

Sao*_*wan 5

如果您尝试添加带有指向单元格的链接的 UITextView,并且希望在用户点击除链接之外的任何内容时调用didSelectRow,那么您应该使用hitTest:withEvent:

斯威夫特 3

override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
    // location of the tap
    var location = point
    location.x -= self.textContainerInset.left
    location.y -= self.textContainerInset.top

    // find the character that's been tapped
    let characterIndex = self.layoutManager.characterIndex(for: location, in: self.textContainer, fractionOfDistanceBetweenInsertionPoints: nil)
    if characterIndex < self.textStorage.length {
        // if the character is a link, handle the tap as UITextView normally would
        if (self.textStorage.attribute(NSLinkAttributeName, at: characterIndex, effectiveRange: nil) != nil) {
            return self
        }
    }

    // otherwise return nil so the tap goes on to the next receiver
    return nil
}
Run Code Online (Sandbox Code Playgroud)

我写了一篇关于这个的文章,里面有更多的细节。


n00*_*mer 3

一种可能的(且复杂的)解决方案是UIView在.UITapGestureRecogniserUITextView

  • 首先,您需要找到NSRange您的链接。

  • 转换NSRangeUITextRange

  • 使用类似于以下的代码UITapGestureRecogniserUITextView.

    UITextPosition *pos = textView.endOfDocument;// textView ~ UITextView
    
    for (int i = 0; i < words*2 - 1; i++){// *2 since UITextGranularityWord considers a whitespace to be a word
    
        UITextPosition *pos2 = [textView.tokenizer positionFromPosition:pos toBoundary:UITextGranularityWord inDirection:UITextLayoutDirectionLeft];
        UITextRange *range = [textView textRangeFromPosition:pos toPosition:pos2];
        CGRect resultFrame = [textView firstRectForRange:(UITextRange *)range ];
    
        UIView* tapViewOnText = [[UIView alloc] initWithFrame:resultFrame];
        [tapViewOnText addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(targetRoutine)]];
        tapViewOnText.tag = 125;
        [textView addSubview:tapViewOnText];
        [tapViewOnText release];
    
        pos = pos2;
    
    Run Code Online (Sandbox Code Playgroud)

    }

我在这段代码中所做的是,获取UITextRange相关文本,获取它firstRectForRange并添加一个透明的可点击的UIView并在其顶部

您必须使用 some 获取链接的范围regEx,将其转换为UITextRange,并在其上添加可点击的内容UIViews。如果单个链接中可能有多个链接,textView您可以添加一个tag与其“链接”相对应的链接,并通过检查其标签在目标方法中打开该链接。

注意:如果您的UITextViews 普遍不可编辑,您可能想尝试TTTAttributedLabel一下。这就是我在我的UITableViewCells