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
紧迫原因,例如正在显示其他文本,则可以使用UILabel
与UITapGestureRecognizer
结合来获得所需的效果。
否则,你可以用一个实际的UIWebView
代替。
你有没有尝试过设置textview.delaysContentTouches = NO;
? 也许这可能有帮助。
Swift 4解决scheme
- 使用轻击手势识别器处理链接
- 无论
isSelectable
是true
还是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) }