在 ASTextNode AsyncDisplayKit 中检测 Link 或 URL

Detect Link or URL in ASTextNode AsyncDisplayKit

我一直在尝试使用 AsyncDisplayKit 框架,我需要检测文本中的 url。

我已经使用 ASTextNode 但找不到任何 api 来检测链接。

我读到有 属性 linkAttributeNames 用于 url 检测,但找不到任何示例如何做。

有人可以帮助我如何使用上面的class吗?

谢谢

对于 link 检测,您需要使用外部库。 我会推荐 https://github.com/twitter/twitter-text 可以用cocoapods安装。

然后你需要将 TwitterTextEntity* 转换为 NSTextCheckingResult*。

你可以使用这个类别的 NSString:

- (NSArray <NSTextCheckingResult *>*)textCheckingResultsForURLs {
    NSArray *twitterEntitiesArray = [TwitterText URLsInText:self];
    NSMutableArray *textCheckingResultsArray = [[NSMutableArray alloc] initWithCapacity:[twitterEntitiesArray count]];

    for (TwitterTextEntity *twitterTextEntity in twitterEntitiesArray) {
        NSString *textCheckingResultUTF8 = [[self substringWithRange:twitterTextEntity.range] stringPercentEncode];

        NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"%@", textCheckingResultUTF8]];

        NSTextCheckingResult *result = [NSTextCheckingResult linkCheckingResultWithRange:twitterTextEntity.range URL:url];
        [textCheckingResultsArray addObject:result];
    }

    return textCheckingResultsArray;
}

这样使用:

NSArray *links = [yourString textCheckingResultsForURLs];

然后您需要像这样将计算范围添加到 NSMutableAttributedString:

for (NSTextCheckingResult *textCheckingResult in links) {

        NSMutableDictionary *linkAttributes = [[NSMutableDictionary alloc] initWithDictionary:@{NSForegroundColorAttributeName : [UIColor whiteColor]}];

        linkAttributes[@"TextLinkAttributeNameURL"] = [NSURL URLWithString:textCheckingResult.URL.absoluteString];

        [string addAttributes:linkAttributes range:textCheckingResult.range];
    }

然后您需要配置ASTextNode 节点以突出显示特定范围。所以在父节点添加:

_textLabelNode.delegate = self;
_textLabelNode.userInteractionEnabled = YES;
_textLabelNode.linkAttributeNames = @[@"TextLinkAttributeNameURL"];

+

- (void)didLoad {
    // For text node
    self.layer.as_allowsHighlightDrawing = YES;

    [super didLoad];
}

#pragma mark - ASTextNodeDelegate

- (BOOL)textNode:(ASTextNode *)richTextNode shouldHighlightLinkAttribute:(NSString *)attribute value:(id)value atPoint:(CGPoint)point {
    return YES;
}

- (void)textNode:(ASTextNode *)richTextNode tappedLinkAttribute:(NSString *)attribute value:(NSURL *)URL atPoint:(CGPoint)point textRange:(NSRange)textRange {
NSLog(@"TODO");
}

这对我有用。希望,什么都没有忘记。

为Swift3.0

func addLinkDetection(_ text: String, highLightColor: UIColor, delegate: ASTextNodeDelegate) {
    self.isUserInteractionEnabled = true
    self.delegate = delegate

    let types: NSTextCheckingResult.CheckingType = [.link]
    let detector = try? NSDataDetector(types: types.rawValue)
    let range = NSMakeRange(0, text.characters.count)
    if let attributedText = self.attributedText {
        let mutableString = NSMutableAttributedString()
        mutableString.append(attributedText)
        detector?.enumerateMatches(in: text, range: range) {
            (result, _, _) in
            if let fixedRange = result?.range {
                mutableString.addAttribute(NSUnderlineColorAttributeName, value: highLightColor, range: fixedRange)
                mutableString.addAttribute(NSLinkAttributeName, value: result?.url, range: fixedRange)
                mutableString.addAttribute(NSForegroundColorAttributeName, value: highLightColor, range: fixedRange)

            }
        }
        self.attributedText = mutableString
    }        
}

将代表添加到您的 viewController:

/// Delegate function for linkDetection
func textNode(_ textNode: ASTextNode, shouldHighlightLinkAttribute attribute: String, value: Any, at point: CGPoint) -> Bool {
    return true
}

func textNode(_ textNode: ASTextNode, tappedLinkAttribute attribute: String, value: Any, at point: CGPoint, textRange: NSRange) {
    guard let url = value as? URL else { return }
 }