在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
,则可以在TextView中添加TAP识别器,并在TAP位置获取字符串属性。当您找到链接时,您可以立即打开它。
我写了一个要解决iOS 7/8的要旨。这是UITextView
的轻量级扩展,它也会转发-[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
// ...
并添加您的回调:
- (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版本:
点击识别器:
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)
}
}
UITextView
可选吗?尝试:
self.textView.selectable = YES;
编辑:
我开始认为,也许长时间的命中是与Apple所说的相反的唯一途径。检查此链接,也许会有所帮助。
正如nnarayann所述,cchlinktextview避免了延迟的点击识别问题。该库实现了自己的手势识别器,现在可以在1.0版中使用。
swift 4 解决方案
- 使用龙头手势识别器处理链接
-
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 url = textView.textStyling(at: textPosition, in: .forward)?[NSAttributedStringKey.link.rawValue],
let urlString = (url as? String) ?? (url as? URL)?.absoluteString,
urlString == "myurl"
else { return }
let url = URL(string: urlString)!
// Do whatever you want with this URL, such as
UIApplication.shared.openURL(url)
}
有时它在iOS模拟器上不起作用,或者仅在点击&保持。
您应该在真实的设备上对其进行测试。
不要忘记将其设置为selectable
。
如果没有任何迫切的理由使用UITextView
,例如显示其他文本,您可以使用与UITapGestureRecognizer
结合的UILabel
来获得您正在寻找的效果为了。
否则,您可以使用实际的UIWebView
。
您是否尝试过设置textview.delaysContentTouches = NO;
?也许这可能会有所帮助。
如果您不需要编辑,则可以使用此信息:
textView.isEditable = true
func textViewShouldBeginEditing(_ textView: UITextView) -> Bool
{
return false
}
使用此方法
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
return true
}