Определить ссылку или URL в ASTextNode AsyncDisplayKit
Я пытался использовать AsyncDisplayKit
Framework, у меня есть требование для определения URL в тексте.
я использовал ASTextNode
но не смог найти API для обнаружения ссылок.
Я читал, что есть собственность linkAttributeNames
используется для определения URL, но не может найти ни одного примера, как это сделать.
Может ли кто-нибудь помочь мне, как использовать вышеупомянутый класс?
Спасибо
2 ответа
Для Swift 3.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 }
}
Для обнаружения ссылок вам нужно использовать внешнюю библиотеку. Я бы порекомендовал 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");
}
Это работает для меня. Надеюсь, не забыла ни о чем.