你如何使文本中的UITextView检测链接部分,仍然有userInteractionDisabled?

我有一个textView分层的tableView细胞。 我需要用户点击tableView行来打开一个viewController,但如果textView有一个链接,它必须是可点击的,就是这样,没有复制,select等

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

textView.userInteractionEnabled=NO; textView.dataDetectorTypes =UIDataDetectorTypeLink; 

didSelectRowAtIndexPath不被调用,我明白为什么,但如何实现呢?

编辑:

我正在寻找的是能够具体确定链接,并允许用户点击链接打开浏览器,并禁用textView的其余部分的交互。 如上所述,整行也应该是可点击的。

附加是我的tableView单元格行的图像,显​​示链接被检测到,交互也是可能的,但是这将禁用didSelectRowAtIndexPath区域内的didSelectRowAtIndexPath

在这里输入图像说明

一个可能的(也是复杂的)解决scheme是在你的UITextView使用UITapGestureRecogniserUITapGestureRecogniser

  • 首先,你需要find链接的NSRange

  • NSRange转换为UITextRange

  • 使用与以下类似的代码在UITextView中的链接文本上添加一个UITapGestureRecogniser

     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; 

    }

我在这段代码中做了什么,得到了相关文本的firstRectForRange ,得到它的firstRectForRange并在它firstRectForRange添加了一个透明的可点击的UIView

你将不得不使用一些regEx得到你的链接的范围,将其转换为UITextRange ,并添加可轻敲的UITextRange 。 如果在单个textView视图中可能存在多个链接,则可以为与其“链接”相对应的每个视图添加一个tag ,并通过检查标记来打开目标方法中的链接。

注意:如果你的UITextView是普遍不可编辑的,你可能想尝试TTTAttributedLabel 。 这就是我在我的UITableViewCells所做的

也许它会为你的目的确定:

 textView.editable=NO; textView.userInteractionEnabled=YES; textView.dataDetectorTypes =UIDataDetectorTypeLink; 

但实际上UITextView在内部使用了UIWebView部件,这种方式可能会在表格单元格中缓慢。 在这里输入图像说明

我可以build议使用CoreTextNSAttributedString的触摸。 例如,你可以阅读这个SOpost 。

如果你正在尝试添加一个UITextView链接到一个单元格,并且希望didSelectRow在用户点击除链接之外的任何东西时被调用,那么你应该使用hitTest:withEvent:

Swift 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 } 

我写了一篇关于这个更详细的文章 。