在 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 }
}
我一直在尝试使用 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 }
}