Ios UITextView链接点击识别延迟
在iOS 7应用程序中,我有一个带有链接的Ios UITextView链接点击识别延迟,ios,objective-c,uitextview,Ios,Objective C,Uitextview,在iOS 7应用程序中,我有一个带有链接的UITextView,但点击链接不会触发。它只对笨拙的“点击并按住”做出响应。我希望它在用户点击它时立即响应,就像UIWebView链接点击的工作方式一样。以下是我的设置: - (void)viewDidLoad { [super viewDidLoad]; NSMutableAttributedString *text = [[NSMutableAttributedString alloc] initWithString:@"Lore
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中发生:(((((((()不确定为什么这个答案被否决,因为我看到了相同的行为