Ios UITextView链接点击识别延迟

Ios UITextView链接点击识别延迟,ios,objective-c,uitextview,Ios,Objective C,Uitextview,在iOS 7应用程序中,我有一个带有链接的UITextView,但点击链接不会触发。它只对笨拙的“点击并按住”做出响应。我希望它在用户点击它时立即响应,就像UIWebView链接点击的工作方式一样。以下是我的设置: - (void)viewDidLoad { [super viewDidLoad]; NSMutableAttributedString *text = [[NSMutableAttributedString alloc] initWithString:@"Lore

在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
方法文档中说:“如果用户点击或长按URL链接,文本视图将调用此方法”。长按在工作,但水龙头似乎不工作


是否有人知道如何立即对此作出响应?

如果没有任何迫切的理由使用
UITextView
,例如显示其他文本,您可以使用
UILabel
UIAPTgestureRecognitizer
结合使用,以获得您想要的效果


否则,您可以使用实际的
UIWebView

是否可以选择
UITextView
?。尝试:

self.textView.selectable = YES;
编辑:


我开始认为,也许长时间的媒体报道是唯一一种与苹果所说相反的方式。选中此选项,可能会有所帮助。

您是否尝试过设置
textview.delaysContentTouches=NO?也许这会有所帮助。

正如纳拉安所提到的那样,避免了延迟点击识别的问题。此库实现了自己的手势识别器,目前已在1.0版中提供。

如果您仍想使用本机
UITextView
,您可以将点击识别器添加到文本视图中,并在点击位置获取字符串属性。找到链接后,可以立即打开它

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

这里有一个简单的例子:下面的例子只适用于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

// ...
let tapRecognizer = UITapGestureRecognizer(target: self, action: Selector("tappedTextView:"))
myTextView.addGestureRecognizer(tapRecognizer)
myTextView.selectable = true
并添加您的回拨:

- (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];
    }
}
和swift版本:

点击识别器:

// ...

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

// ...
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)
        }

        }

有时它在iOS模拟器上不起作用,或者只在点击并按住时起作用

你应该在真正的设备上测试它


不要忘记将其设置为可选择的Swift 4解决方案


  • 使用点击手势识别器处理链接
  • 无论
    isSelectable
    true
    还是
    false
    ,它都有效


如果不需要编辑,可以使用以下选项:

textView.isEditable = true
func textViewShouldBeginEditing(_ textView: UITextView) -> Bool
{
    return false
}


我有-这是我的第一个想法,包含在上面的代码中。我知道UITextView继承了UIScrollView,所以我认为它与此有某种联系。这也是我的第一直觉。然后,我建议您继续通过
触摸开始
&它的兄弟和
属性索引
,并检查
NSLINK属性
是否存在。您将如何执行此操作?这听起来像是重新实现了链接检测……还有,attributesAtIndex方法在哪里?是的,看起来确实如此。attributesAtIndex在该UITextView的NSAttributed字符串上可用。我可以在明天晚些时候发布一些代码。问题不在于链接不起作用。这是因为用户必须对其进行延迟触摸。可能是iOS 7.1中现在修复的一个bug。尝试禁用滚动作为解决方法。我正在使用7.1-昨天刚刚更新,并验证了它在7.0和7.1中的工作原理。在设置URL之前,找到了可能的解决方法:
[self.textView setText:nil]
<代码>self.textView.dataDetectorTypes=UIDataDetectorTypeLink
[self.textView.scrollEnabled:否]我开始认为,也许长时间的印刷是唯一一种与苹果所说相反的方式。检查这个,也许会有帮助。我在UITextView中做了很多attributedString工作,所以我更喜欢这个而不是构建HTML字符串。另外,我需要特定的文本点可供选择,而不是整个文本,所以UILabel也不存在。是的,但是没有触摸突出显示。这正是我需要的。不过有两点需要注意:1:textView需要可选择才能工作(希望我能禁用它)2:attributes的
NSLinkAttributeName
键产生一个NSURL,因此上面的代码在
URLWithString
part@BobVork谢谢我编辑了我的原始回复,以反映您的观点。我刚刚在iOS 7上尝试了这一点,但textView似乎根本找不到链接属性。你在iOS 7上有过这样的运气吗?@BobWork没错,我记得有一些跨版本的问题。最终,在iOS 7上使用
textstylingaatposition:inDirection:
获取属性变得有点棘手。我假设它与长度为0的textPosition有关,因此属性化字符串没有字符来实际承载任何链接信息。只是一个想法。最后,我写了一篇在iOS 7和iOS 8中适用的要点:Swift 4:
@objc func tappedTextView(tappostate:uigestureRecognitizer){let textView=tappostate.view as!UITextView let tapposition=tappostation.location(in:textView)let textPosition=textView.closestPosition(to:tappostation)让attr=textView.textStyling(在:textPosition!中:。forward)!如果让url:url=attr[NSAttributedStringKey.link.rawValue]作为?url{UIApplication.shared.open(url,options:[:],completionHandler:nil)}
Nice library!在我的swift项目中,只花了2分钟就包含pod并调整了现有代码。工作完美。此外,该属性采用任何类型的值,而不是NSURL。如果您需要传递其他内容,如索引,那么它就是完美的。谢谢链接点击识别延迟仍在iOS9中发生:(((((((()不确定为什么这个答案被否决,因为我看到了相同的行为