Closed lohenyumnam closed 5 years ago
You could use something like twitter-text to detect the entities. Then use those ranges to add a attributes to the hashtags, including a URL.
NSMutableDictionary *linkAttributes = [[NSMutableDictionary alloc] initWithDictionary:@{NSForegroundColorAttributeName : [UIColor whiteColor]}];
linkAttributes[@"TextLinkAttributeNameURL"] = [NSURL URLWithString:url];
[string addAttributes:linkAttributes range:range];```
Here is the Solution base on the @ay8s 's guide In Slack
import UIKit
import AsyncDisplayKit
import twitter_text
class ViewController: ASViewController<ASDisplayNode> {
private var kLinkAttributeName = "PlaceKittenNodeLinkAttributeName"
let textNode = ASTextNode()
let text: NSString = "#Spotify is now free on #mobile and tablet. Listen to the right #music and #podcasts, wherever you are. With #Spotify, you have access to a world of #music and @Lohen"
init() {
super.init(node: .init())
self.node.automaticallyManagesSubnodes = true
self.node.automaticallyRelayoutOnSafeAreaChanges = true
self.node.isOpaque = true
self.node.layoutSpecBlock = {
[weak self] (_, _) -> ASLayoutSpec in
guard let self = self else { return ASLayoutSpec() }
let centerSpec = ASCenterLayoutSpec(centeringOptions: .XY, sizingOptions: [], child: self.textNode)
let layout = ASInsetLayoutSpec(insets: UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0), child: self.textNode)
return centerSpec
}
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func viewDidLoad() {
super.viewDidLoad()
textNode.delegate = self
textNode.isUserInteractionEnabled = true
view.backgroundColor = .white
let updateString = NSMutableAttributedString(string: text as String)
let entities = TwitterText.entities(inText: text as String)
var tag: String = ""
var tags: [String] = [String]()
for entity: TwitterTextEntity in entities {
let r: NSRange = entity.range
if entity.type == TwitterTextEntityType.hashtag {
tag = text.substring(with: r)
print(tag)
let url = URL(string: tag)
if url != nil {
var mutableActiveLinkAttributes: [AnyHashable : Any] = [:]
mutableActiveLinkAttributes[NSAttributedString.Key.foregroundColor] = UIColor.red
if let url = URL(string: url?.absoluteString ?? "") {
mutableActiveLinkAttributes[tag] = url
tags.append(tag)
}
if let mutableActiveLinkAttributes = mutableActiveLinkAttributes as? [NSAttributedString.Key : Any] {
updateString.addAttributes(mutableActiveLinkAttributes, range: r)
}
}
}
if entity.type == TwitterTextEntityType.screenName {
tag = text.substring(with: r)
print(tag)
let url = URL(string: tag)
if url != nil {
var mutableActiveLinkAttributes: [AnyHashable : Any] = [:]
mutableActiveLinkAttributes[NSAttributedString.Key.foregroundColor] = UIColor.blue
if let url = URL(string: url?.absoluteString ?? "") {
mutableActiveLinkAttributes[tag] = url
tags.append(tag)
}
if let mutableActiveLinkAttributes = mutableActiveLinkAttributes as? [NSAttributedString.Key : Any] {
updateString.addAttributes(mutableActiveLinkAttributes, range: r)
}
}
}
}
textNode.linkAttributeNames = tags
textNode.attributedText = updateString
}
}
extension ViewController: ASTextNodeDelegate {
func textNode(_ textNode: ASTextNode!, tappedLinkAttribute attribute: String!, value: Any!, at point: CGPoint, textRange: NSRange) {
if let tag = attribute{
print(tag)
}
}
}
Can any one point me to right direction. I want to detect tap on hashtags and add action targets on ASTextNode