在 UITextView 中点击 NSLinkAttributeName link 在 iOS 9 中不起作用
Tapping a NSLinkAttributeName link in UITextView not working in iOS 9
我有一个带有属性文本的 UITextView
,其设置如下:
NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:@"This is a message.\nClick here for more info"];
textView.linkTextAttributes = @{NSUnderlineStyleAttributeName : @(NSUnderlineStyleSingle)};
NSRange linkRange = [attributedString.string rangeOfString:@"Click here for more info"];
[attributedString addAttribute:NSLinkAttributeName value:@"" range:linkRange];
textView.attributedText = attributedString;
UITapGestureRecognizer *tapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(infoTapped:)];
[textView addGestureRecognizer:tapRecognizer
然后我像这样抓住一个水龙头:
- (void)infoTapped:(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];
NSString *link = attributes[NSLinkAttributeName];
if (link) {
// Do stuff
}
}
在 iOS 10 中,这工作正常,我能够检测到 NSLinkAttributeName
属性。
但是,在 iOS 9 中调用 [textView closestPositionToPoint:tapLocation]
returns nil
之后我无法做任何事情。
顺便说一句。我的 textview 将 editable
和 selectable
都设置为 NO。我知道有人说 selctable
需要设置为 YES,但我不确定这是真的。首先,它在 iOS 10 中没有可选择的情况下工作正常。其次,如果我将它设置为可选择它确实有效,但只是有点。我确实在 iOS 9 中获得了水龙头,但它只能不稳定地工作(在 9 和 10 中)。有时它会记录水龙头,有时不会。基本上,当我看到 link 突出显示时,就像您在浏览器中单击 link 一样,它不会注册。此外,现在可以选择我不想要的文本视图中的文本。
为什么要 select link 使用点按手势? UITextView 具有完善的 links 识别功能。我无法回答为什么您的解决方案在 iOS 9 上无法正常工作,但我可以建议您以另一种方式处理 links。这也适用于 iOS 9。
NSMutableAttributedString *str = [[NSMutableAttributedString alloc] initWithString:@"This is a message.\nClick here for more info" attributes:nil];
NSRange range = [str.string rangeOfString:@"Click here for more info"];
// add a value to link attribute, you'll use it to determine what link is tapped
[str addAttribute:NSLinkAttributeName value:@"ShowInfoLink" range:range];
self.textView.linkTextAttributes = @{NSUnderlineStyleAttributeName : @(NSUnderlineStyleSingle)};
self.textView.attributedText = str;
// set textView's delegate
self.textView.delegate = self;
然后实现linkUITextViewDelegate的相关方法:
- (BOOL)textView:(UITextView *)textView shouldInteractWithURL:(NSURL *)URL inRange:(NSRange)characterRange interaction:(UITextItemInteraction)interaction
{
if ([URL.absoluteString isEqualToString:@"ShowInfoLink"]) {
// Do something
}
return NO;
}
要使其正常工作,您必须设置 selectable = YES 并检查 Storyboard 中的 links 标志才能检测到 links。
我有一个带有属性文本的 UITextView
,其设置如下:
NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:@"This is a message.\nClick here for more info"];
textView.linkTextAttributes = @{NSUnderlineStyleAttributeName : @(NSUnderlineStyleSingle)};
NSRange linkRange = [attributedString.string rangeOfString:@"Click here for more info"];
[attributedString addAttribute:NSLinkAttributeName value:@"" range:linkRange];
textView.attributedText = attributedString;
UITapGestureRecognizer *tapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(infoTapped:)];
[textView addGestureRecognizer:tapRecognizer
然后我像这样抓住一个水龙头:
- (void)infoTapped:(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];
NSString *link = attributes[NSLinkAttributeName];
if (link) {
// Do stuff
}
}
在 iOS 10 中,这工作正常,我能够检测到 NSLinkAttributeName
属性。
但是,在 iOS 9 中调用 [textView closestPositionToPoint:tapLocation]
returns nil
之后我无法做任何事情。
顺便说一句。我的 textview 将 editable
和 selectable
都设置为 NO。我知道有人说 selctable
需要设置为 YES,但我不确定这是真的。首先,它在 iOS 10 中没有可选择的情况下工作正常。其次,如果我将它设置为可选择它确实有效,但只是有点。我确实在 iOS 9 中获得了水龙头,但它只能不稳定地工作(在 9 和 10 中)。有时它会记录水龙头,有时不会。基本上,当我看到 link 突出显示时,就像您在浏览器中单击 link 一样,它不会注册。此外,现在可以选择我不想要的文本视图中的文本。
为什么要 select link 使用点按手势? UITextView 具有完善的 links 识别功能。我无法回答为什么您的解决方案在 iOS 9 上无法正常工作,但我可以建议您以另一种方式处理 links。这也适用于 iOS 9。
NSMutableAttributedString *str = [[NSMutableAttributedString alloc] initWithString:@"This is a message.\nClick here for more info" attributes:nil];
NSRange range = [str.string rangeOfString:@"Click here for more info"];
// add a value to link attribute, you'll use it to determine what link is tapped
[str addAttribute:NSLinkAttributeName value:@"ShowInfoLink" range:range];
self.textView.linkTextAttributes = @{NSUnderlineStyleAttributeName : @(NSUnderlineStyleSingle)};
self.textView.attributedText = str;
// set textView's delegate
self.textView.delegate = self;
然后实现linkUITextViewDelegate的相关方法:
- (BOOL)textView:(UITextView *)textView shouldInteractWithURL:(NSURL *)URL inRange:(NSRange)characterRange interaction:(UITextItemInteraction)interaction
{
if ([URL.absoluteString isEqualToString:@"ShowInfoLink"]) {
// Do something
}
return NO;
}
要使其正常工作,您必须设置 selectable = YES 并检查 Storyboard 中的 links 标志才能检测到 links。