UITextView链接点击识别被延迟

在iOS 7应用程序中,我有一个链接的UITextView ,但点击链接不会触发。 它只响应一个尴尬的“点击并按住”。 我希望它在用户点击它时立即响应,就像UIWebView链接点击是如何工作的。 这是我的设置:

 - (void)viewDidLoad { [super viewDidLoad]; NSMutableAttributedString *text = [[NSMutableAttributedString alloc] initWithString:@"Lorem ipsum dolor sit er elit lamet, consectetaur cillium adipisicing pecu, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua."]; [text addAttribute:NSLinkAttributeName value:@"myurl://tapped" range:NSMakeRange(6, 16)]; self.textView.attributedText = text; self.textView.editable = NO; self.textView.delaysContentTouches = NO; } - (BOOL)textView:(UITextView *)textView shouldInteractWithURL:(NSURL *)URL inRange:(NSRange)characterRange { if ([[URL scheme] isEqualToString:@"myurl"]) { // Handle tap return NO; } return YES; } 

shouldInteractWithURL方法的Apple文档指出:“如果用户点击或长按URL链接,则文本视图调用此方法”。 长按正在工作,但水龙头似乎没有工作。

有谁知道如何得到这个立即作出回应?

UITextView可选的吗? 试试:

 self.textView.selectable = YES; 

编辑:

我开始认为,长时间按压是唯一的办法,与苹果所说的相反。 检查这个链接 ,也许会有所帮助。

如果您仍想使用原生UITextView ,则可以在您的文本视图中添加水龙头识别器,并在水龙头位置获取string属性。 当你find一个链接,你可以立即打开它。

我写了一个为iOS 7/8解决这个问题的Gist。 这是UITextView的轻量级扩展,它也转发-[UITextViewDelegate textView:shouldInteractWithURL:inRange:]并公开内部轻-[UITextViewDelegate textView:shouldInteractWithURL:inRange:]手势识别器。

https://gist.github.com/benjaminbojko/c92ac19fe4db3302bd28

下面是一个简单的例子:下面的例子只适用于iOS 8.请参阅上面的iOS 7 + 8支持要点。

添加您的水龙头识别器:

 // ... UITapGestureRecognizer *tapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tappedTextView:)]; [myTextView addGestureRecognizer:tapRecognizer]; myTextView.selectable = YES; // otherwise the gesture won't recognize // ... 

并添加你的callback:

 - (void)tappedTextView:(UITapGestureRecognizer *)tapGesture { if (tapGesture.state != UIGestureRecognizerStateEnded) { return; } UITextView *textView = (UITextView *)tapGesture.view; CGPoint tapLocation = [tapGesture locationInView:textView]; UITextPosition *textPosition = [textView closestPositionToPoint:tapLocation]; NSDictionary *attributes = [textView textStylingAtPosition:textPosition inDirection:UITextStorageDirectionForward]; NSURL *url = attributes[NSLinkAttributeName]; if (url) { [[UIApplication sharedApplication] openURL:url]; } } 

和迅捷版本:

点按识别器:

 let tapRecognizer = UITapGestureRecognizer(target: self, action: Selector("tappedTextView:")) myTextView.addGestureRecognizer(tapRecognizer) myTextView.selectable = true 

回电话:

 func tappedTextView(tapGesture: UIGestureRecognizer) { let textView = tapGesture.view as! UITextView let tapLocation = tapGesture.locationInView(textView) let textPosition = textView.closestPositionToPoint(tapLocation) let attr: NSDictionary = textView.textStylingAtPosition(textPosition, inDirection: UITextStorageDirection.Forward) if let url: NSURL = attr[NSLinkAttributeName] as? NSURL { UIApplication.sharedApplication().openURL(url) } } 

正如nnarayann提到的, CCHLinkTextView避免了延迟触摸识别的问题。 这个库实现了自己的手势识别器,现在在1.0版本中可用。

有时它不能在iOS模拟器上工作,或者只有当你按住时才能工作。

你应该在真实的设备上testing它。

不要忘记将其设置为selectable

如果没有任何使用UITextView紧迫原因,例如正在显示其他文本,则可以使用UILabelUITapGestureRecognizer结合来获得所需的效果。

否则,你可以用一个实际的UIWebView代替。

你有没有尝试过设置textview.delaysContentTouches = NO; ? 也许这可能有帮助。

Swift 4解决scheme


  • 使用轻击手势识别器处理链接
  • 无论isSelectabletrue还是false ,都可以

 let tapRecognizer = UITapGestureRecognizer(target: self, action: #selector(handleLinkTap(_:))) textView.addGestureRecognizer(tapRecognizer) @objc func handleLinkTap(_ recognizer: UITapGestureRecognizer) { let tapLocation = recognizer.location(in: textView) guard let textPosition = textView.closestPosition(to: tapLocation), let urlString = textView.textStyling(at: textPosition, in: .forward)?[NSAttributedStringKey.link.rawValue] as? String, urlString == "myurl" else { return } let url = URL(string: urlString)! // Do whatever you want with this URL, such as UIApplication.shared.openURL(url) }