How to use UITableView and NSLink together in Swift iOS?

How to use UITableView and NSLink together in Swift iOS?



Extension Code:


extension String
func accentTagAndLink(tags:Array<String>) -> NSMutableAttributedString

let attributedString:NSMutableAttributedString = NSMutableAttributedString(string: self)
var NSContents = self as NSString

for tagChild in tags
if !tagChild.starts(with: "<")
let range = NSContents.range(of: "#" + tagChild)
var changeString = ""

for _ in 0..<tagChild.count
changeString += "$"


NSContents = NSContents.replacingOccurrences(of: tagChild, with: changeString, options: .literal, range: range) as NSString
attributedString.addAttribute(.link, value: tagChild, range: range)
attributedString.addAttribute(.foregroundColor, value: UIColor(red: 79/255, green: 205/255, blue: 255/255, alpha: 1), range: range)



return attributedString




TableViewCell :


class PostCell: TableViewCell
@IBOutlet weak var postContent: UITextView!



in mainViewController


class PostViewController: UIViewController, UITableViewDataSource, UITableViewDelegate,UITextViewDelegate

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
let cell = postTableView.dequeueReusableCell(withIdentifier: "PostCell", for: indexPath) as! PostCell
let post = postList[indexPath.row]
let tags = (post["Content"] as! String).FindTagAtString()
cell.postContent.delegate = self
cell.postContent.isSelectable = true
cell.postContent.isEditable = false
cell.postContent.isUserInteractionEnabled = true
cell.postContent.dataDetectorTypes = UIDataDetectorTypes.link
cell.postContent.attributedText = (post["Content"] as! String).accentTagAndLink(tags: tags)
let tap = MyTapGesture(target: self, action: #selector(self.tapTextView))
tap.indexPath = indexPath
cell.postContent.addGestureRecognizer(tap)


func textView(_ textView: UITextView, shouldInteractWith URL: URL, in characterRange: NSRange, interaction: UITextItemInteraction) -> Bool
print(URL)
return true


func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)
print("cell tap")
movePostDetail(indexPath)

@objc func tapTextView(sender:MyTapGesture)
print("cell tap")
movePostDetail(sender.indexPath)





MyTapGesture :


class MyTapGesture: UITapGestureRecognizer
var indexPath:IndexPath!



Content is NormalText + TagText


NormalText + TagText



If tap NormalText to run movePostDetail and if tap TagText to run print(URL) but always movePostDetail when addGestureRecognizer


addGestureRecognizer



How to use together



It worked well when I took TTTAttributedLabel, but because of crash so i haven't used TTTAttributedLabel.


TTTAttributedLabel


TTTAttributedLabel




1 Answer
1



I advice you to use a CUSTOM ATTRIBUTE NAME and handle the tap by yourself.



Solution in Swift 4


override func awakeFromNib()
super.awakeFromNib()
// Initialization code
let tapGes = UITapGestureRecognizer(target: self, action: #selector(TableViewCell.handleTap(sender:)))
contentTf.addGestureRecognizer(tapGes)

let attributeName = "CustomAttributeName"
let attStr = NSAttributedString(string: "https", attributes: [NSAttributedStringKey(rawValue: attributeName):"https"])

contentTf.attributedText = attStr

@objc func handleTap(sender: UITapGestureRecognizer) -> Void
let myTextView = sender.view as! UITextView
let layoutManager = myTextView.layoutManager

// location of tap in myTextView coordinates and taking the inset into account
var location = sender.location(in: myTextView)
location.x -= myTextView.textContainerInset.left;
location.y -= myTextView.textContainerInset.top;

// character index at tap location
let characterIndex = layoutManager.characterIndex(for: location, in: myTextView.textContainer, fractionOfDistanceBetweenInsertionPoints: nil)

// if index is valid then do something.
if characterIndex < myTextView.textStorage.length

// print the character index
print("character index: (characterIndex)")

// print the character at the index
let myRange = NSRange(location: characterIndex, length: 1)
let substring = (myTextView.attributedText.string as NSString).substring(with: myRange)
print("character at index: (substring)")

// check if the tap location has a certain attribute
let attributeName = "CustomAttributeName"
let attributeValue = myTextView.attributedText.attribute(NSAttributedStringKey(rawValue: attributeName), at: characterIndex, effectiveRange: nil) as? String
if let value = attributeValue
print("You tapped on (attributeName) and the value is: (value)")






TEST


character index: 3
character at index: p
You tapped on CustomAttributeName and the value is: https





I did not know addGestureRecognizer is in TableViewCell now. thank you
– Adam
Aug 23 at 5:51






By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Popular posts from this blog

𛂒𛀶,𛀽𛀑𛂀𛃧𛂓𛀙𛃆𛃑𛃷𛂟𛁡𛀢𛀟𛁤𛂽𛁕𛁪𛂟𛂯,𛁞𛂧𛀴𛁄𛁠𛁼𛂿𛀤 𛂘,𛁺𛂾𛃭𛃭𛃵𛀺,𛂣𛃍𛂖𛃶 𛀸𛃀𛂖𛁶𛁏𛁚 𛂢𛂞 𛁰𛂆𛀔,𛁸𛀽𛁓𛃋𛂇𛃧𛀧𛃣𛂐𛃇,𛂂𛃻𛃲𛁬𛃞𛀧𛃃𛀅 𛂭𛁠𛁡𛃇𛀷𛃓𛁥,𛁙𛁘𛁞𛃸𛁸𛃣𛁜,𛂛,𛃿,𛁯𛂘𛂌𛃛𛁱𛃌𛂈𛂇 𛁊𛃲,𛀕𛃴𛀜 𛀶𛂆𛀶𛃟𛂉𛀣,𛂐𛁞𛁾 𛁷𛂑𛁳𛂯𛀬𛃅,𛃶𛁼

Edmonton

Crossroads (UK TV series)