Clickable Link on tableview controller - ios

Hey guys how do I make a link clickable in a table view cell as shown in the image link above ?
The information is from a Json File.
func tableView( tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "albumID", for: indexPath)
let album :[String:Any] = albums[indexPath.row]
cell.textLabel?.text = album["collectionName"] as? String
cell.detailTextLabel?.text = album["artistName"] as? String
return cell
}

You need to have UITextView as detailTextLabel
attributedString.addAttribute(.link, value: "https://developer.apple.com", range: NSRange(location: 30, length: 50))
cell.detailTextLabel?.attributedText = attributedString
and then implement this method
func textView(_ textView: UITextView, shouldInteractWith URL: URL, in characterRange: NSRange, interaction: UITextItemInteraction) -> Bool {
UIApplication.shared.open(URL)
return false
}

You can use the below-mentioned statements to make a link of textView or label either inside tableView, collection view, or using them separately inside viewController.
If you are using textView then you can use this code mentioned below:-
let attributedString = NSMutableAttributedString(string: "Just click here to `register")
let url = URL(string: "https://www.apple.com")!
// Set the 'click here' substring to be the link
attributedString.setAttributes([.link: url], range: NSMakeRange(5, 10))
self.textView.attributedText = attributedString
self.textView.isUserInteractionEnabled = true
self.textView.isEditable = false
// Set how links should appear: blue and underlined
self.textView.linkTextAttributes = [
.foregroundColor: UIColor.blue,
.underlineStyle: NSUnderlineStyle.single.rawValue
]
or
if you are using labels then you can use this code mentioned below:-
var attributedString = NSMutableAttributedString(string: "String with a link", ``attributes: nil)
let linkRange = NSRange(location: 14, length: 4) // for the word "link" in the string above
let linkAttributes = [
NSAttributedString.Key.foregroundColor: UIColor(red: 0.05, green: 0.4, blue: 0.65, alpha: 1.0),
NSAttributedString.Key.underlineStyle: NSNumber(value: NSUnderlineStyle.single.rawValue)
]
attributedString.setAttributes(linkAttributes, range: linkRange)
// Assign attributedText to UILabel
label.attributedText = attributedString```

Related

Change attributed String dynamically

I have a TableViewCell in which I have a clickable textView:
let linkTextView: UITextView = {
let v = UITextView()
v.backgroundColor = .clear
v.textAlignment = .left
v.isScrollEnabled = false
let padding = v.textContainer.lineFragmentPadding
v.textContainerInset = UIEdgeInsets(top: 0, left: -padding, bottom: 0, right: -padding)
v.tintColor = .darkCustom
v.isEditable = false
v.isSelectable = true
v.translatesAutoresizingMaskIntoConstraints = false
return v
}()
let interactableText = NSMutableAttributedString(string: "Link öffnen")
In Cell I also have these two functions to style it and make it clickable:
func setupTextView(){
interactableText.addAttributes([.underlineStyle: NSUnderlineStyle.single.rawValue,
NSAttributedString.Key.font: UIFont(name: "AvenirNext-Medium", size: 15)!,
NSAttributedString.Key.underlineColor: UIColor.darkCustom],
range: NSRange(location: 0, length: interactableText.length))
interactableText.addAttribute(NSAttributedString.Key.link,
value: "https://www.google.de/?hl=de",
range: NSRange(location: 0, length: interactableText.length))
}
func textView(_ textView: UITextView, shouldInteractWith URL: URL, in characterRange: NSRange) -> Bool {
self.linkTappedCallback!(URL)
return false
}
This setup works. However it's not what I really want. I would like to be able to change the value of the link for each cell. I tried it like this in cellForRowAt:
print(currentWish.link)
cell.interactableText.addAttribute(NSAttributedString.Key.link,
value: currentWish.link,
range: NSRange(location: 0, length: cell.interactableText.length))
But when having it like this and dont set the link inside Cell the textView is no longer clickable. What am I missing here?
With the help of #elarcoiris I am now using this function and it works exactly the way I want it to:
extension UITextView {
func hyperLink(originalText: String, hyperLink: String, urlString: String) {
let style = NSMutableParagraphStyle()
style.alignment = .left
let attributedOriginalText = NSMutableAttributedString(string: originalText)
let linkRange = attributedOriginalText.mutableString.range(of: hyperLink)
let fullRange = NSMakeRange(0, attributedOriginalText.length)
attributedOriginalText.addAttribute(NSAttributedString.Key.link, value: urlString, range: linkRange)
attributedOriginalText.addAttribute(NSAttributedString.Key.paragraphStyle, value: style, range: fullRange)
attributedOriginalText.addAttribute(NSAttributedString.Key.foregroundColor, value: UIColor.darkCustom, range: fullRange)
attributedOriginalText.addAttribute(NSAttributedString.Key.underlineColor, value: UIColor.darkCustom, range: fullRange)
attributedOriginalText.addAttribute(NSAttributedString.Key.font, value: UIFont(name: "AvenirNext-Medium", size: 15)!, range: fullRange)
self.linkTextAttributes = [
kCTForegroundColorAttributeName: UIColor.darkCustom,
kCTUnderlineStyleAttributeName: NSUnderlineStyle.single.rawValue,
] as [NSAttributedString.Key : Any]
self.attributedText = attributedOriginalText
}
}
Usage in cellForRowAt:
let cell = tableView.dequeueReusableCell(withIdentifier: WhishCell.reuseID, for: indexPath) as! WhishCell
cell.linkTextView.hyperLink(originalText: "Link öffnen", hyperLink: "Link öffnen", urlString: currentWish.link)

Add Nsattributed string and string in swift

I having the Dynamic data, I load that data into tableview but these data having the mixing of Attributed and normal strings.
Here I getting the as "Tap here" ,I want to dilate that string with Blue colour and pick on that it need to open the url.
I write following code but it gives error.
Binary operator '+' cannot be applied to operands of type 'String' and
'NSMutableAttributedString'
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "WhatisrewardsTableViewCell", for: indexPath)as! WhatisrewardsTableViewCell
cell.imageview.image = images[indexPath.section][indexPath.row]
cell.titlelbl.text = tilenames[indexPath.section][indexPath.row]
cell.desclbl.text = descriptions[indexPath.section][indexPath.row]
let value = " here.".withTextColor(UIColor.disSatifyclr)
if (cell.desclbl.text?.contains("tap"))!{
// cell.desclbl.text?.attributedString
cell.desclbl.text = descriptions[indexPath.section][indexPath.row] + value
}
cell.desclbl.addLineSpacing()
return cell
}
You can not append the NSAttributedString to String objects. I would suggest that you generate a normal String and then add the attributed parameters to it.
func prepareURLString() -> NSMutableAttributedString {
let masterString = "To navigate to google Tap Here."
let formattedString = NSMutableAttributedString(string: masterString)
let formattedStringAttribute = [
NSAttributedString.Key.font: UIFont.systemFont(ofSize: 13, weight: .regular),
NSAttributedString.Key.foregroundColor: UIColor(red: 51.0/255.0, green: 51.0/255.0, blue: 51.0/255.0, alpha: 1),
] as [NSAttributedString.Key : Any]
let privacyPolicyAttribute = [
NSAttributedString.Key.font: UIFont.systemFont(ofSize: 13, weight: .bold),
NSAttributedString.Key.foregroundColor: UIColor.blue,
NSAttributedString.Key.underlineStyle: 1,
NSAttributedString.Key.link: URL(string: "https://www.google.com")!
] as [NSAttributedString.Key : Any]
formattedString.addAttributes(formattedStringAttribute, range: NSMakeRange(0, formattedString.length))
let privacyPolicyRange = (masterString as NSString).range(of: "Tap Here")
formattedString.addAttributes(privacyPolicyAttribute, range: privacyPolicyRange)
return formattedString
}
This function will return a attributed string which you can use however you want. With tableview you can pass some parameters and modify the cell's attributes strings. I have added a google link behind the 'Tap Here' and its showing the output like below :
I hope I got your question right and this helps you in some way.

UITextContainerView hidding clickable link of UITextView

I made a clickable link in a UITextView using NSMutableAttributeString.
All it changes is that the text is highlighted
As we can see : floating over my UITextView there is a UIContainerView (I really don't know if its because of that.. I'm trying)
Here is my UIView code:
class InfoBox: UIView {
let Heading: UITextView = {
let textView = UITextView(frame: CGRect(x: 15, y: 0, width: 200, height: 35))
textView.font = UIFont.systemFont(ofSize: 20)
textView.textColor = UIColor.white
textView.isScrollEnabled = false
textView.backgroundColor = UIColor.clear
textView.isEditable = false
textView.isSelectable = true
return textView
}()
let TextContent: UITextView = {
let textView = UITextView(frame: CGRect(x: 15, y: 27, width: UIScreen.main.bounds.width, height: 30))
textView.font = UIFont.systemFont(ofSize: 17)
textView.textColor = UIColor.white
textView.isScrollEnabled = false
textView.backgroundColor = UIColor.clear
textView.isEditable = false
textView.isSelectable = true
return textView
}()}
The NSAttributedString code:
func transformText(text: String, underlined: Bool, linkURL: String) -> NSAttributedString {
let textRange = NSMakeRange(0, text.characters.count)
let attributedText = NSMutableAttributedString(string: text)
if underlined{
attributedText.addAttribute(NSUnderlineStyleAttributeName , value: NSUnderlineStyle.styleSingle.rawValue, range: textRange)
attributedText.addAttribute(NSUnderlineColorAttributeName , value: UIColor.lightGray, range: textRange)
}
attributedText.addAttribute(NSFontAttributeName , value: UIFont(name: "Helvetica-Light", size: 17)!, range: textRange)
attributedText.addAttribute(NSForegroundColorAttributeName , value: UIColor.lightGray, range: textRange)
if(linkURL != "")
{
let attrib = [NSLinkAttributeName: NSURL(string: linkURL)!]
attributedText.addAttributes(attrib, range: textRange)
}
return attributedText
}
And this is how it is called:
self.TelBox.TextContent.attributedText = transformText(text: self.TelBox.TextContent.text, underlined: true, linkURL: "https://www.google.fr")
Secondary question : is it possible to make a clickable link in a UITextView for a telephone number so that when clicked it calls that number? Did it with a UIButton .
I am not sure what is wrong with your UIContainerView, as far as i can see there's nothing wrong there.
Here's the method to make the link call a number:
func transformText(text: String, underlined: Bool, phoneNumber: String) -> NSAttributedString {
let textRange = NSMakeRange(0, text.characters.count)
let attributedText = NSMutableAttributedString(string: text)
if underlined{
attributedText.addAttribute(NSAttributedStringKey.underlineStyle , value: NSUnderlineStyle.styleSingle.rawValue, range: textRange)
attributedText.addAttribute(NSAttributedStringKey.underlineColor , value: UIColor.lightGray, range: textRange)
}
attributedText.addAttribute(NSAttributedStringKey.font , value: UIFont(name: "Helvetica-Light", size: 17)!, range: textRange)
attributedText.addAttribute(NSAttributedStringKey.foregroundColor , value: UIColor.lightGray, range: textRange)
if(phoneNumber != "")
{
let attrib = [
NSAttributedStringKey.link: URL(string: "tel://" + phoneNumber.replacingOccurrences(of: " ", with: ""))]
attributedText.addAttributes(attrib, range: textRange)
}
return attributedText
}
You can use it like this: TextContent.attributedText = transformText(text: "12345", underlined: true, phoneNumber: "12345")

UITextView with hyperlink text in Swift

I have textfield and i want to getting some text clickable. Below is my code please review and thanks.
let string = "Google"
let linkString = NSMutableAttributedString(string: string)
linkString.addAttribute(NSLinkAttributeName, value: NSURL(string: "https://www.google.com")!, range: NSMakeRange(0, string.characters.count))
linkString.addAttribute(NSFontAttributeName, value: UIFont(name: "HelveticaNeue", size: 25.0)!, range: NSMakeRange(0, string.characters.count))
textView.attributedText = linkString
textView.selectable = true
textView.userInteractionEnabled = true
If you want your UITextView detect link, phoneNumber, address, calendarEvent or simply detect all types than use UIDataDetectorTypes.
let yourstring = "Check Google search. www.google.com"
// Update UITextView font and font size.
textVw.font = UIFont(name: "HelveticaNeue", size: 25)
// Make web links clickable
textVw.isUserInteractionEnabled = true
textVw.isSelectable = true
textVw.isEditable = false
textVw.dataDetectorTypes = UIDataDetectorTypes.link
// Update UITextView content
textVw.text = yourstring
// Update hyperlink text colour.
textVw.linkTextAttributes = [NSForegroundColorAttributeName : UIColor.blue, NSUnderlineStyleAttributeName : NSUnderlineStyle.styleNone.rawValue]
textVw is a object of UITextView as
#IBOutlet var textVw: UITextView!
You can also make text detectable from storyboard as below screenshot.
You can use this code to make your UITextField clickable and open a URL for example
// This is the label
#IBOutlet weak var label: UILabel!
override func loadView() {
super.loadView()
// here is where you make your label clickable
let tap = UITapGestureRecognizer(target: self, action: #selector(self.onClicLabel(sender:)))
label.isUserInteractionEnabled = true
label.addGestureRecognizer(tap)
}
// And here are the functions to open a URL
func onClicLabel(sender:UITapGestureRecognizer) {
openUrl(urlString: "http://www.google.com")
}
func openUrl(urlString:String!) {
let url = URL(string: urlString)!
if #available(iOS 10.0, *) {
UIApplication.shared.open(url, options: [:], completionHandler: nil)
} else {
UIApplication.shared.openURL(url)
}
}

Attributed text with two text alignments

Does anyone know how to achieve two different text alignments in one string?
This is what I want the textView to show:
label value
My code:
let txtView = cell.viewWithTag(77) as! UITextView
let leftStyle = NSMutableParagraphStyle()
leftStyle.alignment = NSTextAlignment.Left
let rightStyle = NSMutableParagraphStyle()
rightStyle.alignment = NSTextAlignment.Right
let attText = NSMutableAttributedString(string: "label", attributes: [NSParagraphStyleAttributeName: leftStyle])
attText.appendAttributedString(NSAttributedString(string: " "))
attText.appendAttributedString(NSAttributedString(string: "value", attributes: [NSParagraphStyleAttributeName: rightStyle]))
txtView.attributedText = attText
What I get instead:
label value
Using NSMutableParagraphStyle with NSTextTab:
let paragraph = NSMutableParagraphStyle()
paragraph.tabStops = [
NSTextTab(textAlignment: .Right, location: 100, options: [:]),
]
let str = "Label\tValue\n"
+ "foo\tbar\n"
let attributed = NSAttributedString(
string: str,
attributes: [NSParagraphStyleAttributeName: paragraph]
)
let view = UITextView(frame: CGRectMake(0, 0, 120, 120))
view.textContainer.lineFragmentPadding = 10
view.attributedText = attributed
Of course, this aligns to "tabstop", but not to the edge of UITextView. When you modify the size of the view, you have to also modify the location of NSTextTab.
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
tableView.register(UITableViewCell.self, forCellReuseIdentifier: "cell")
let cell = Placestableview.dequeueReusableCell(withIdentifier: "cell", for: indexPath);
//first text
let attributestitle = [NSAttributedStringKey.font:
UIFont(name: "Helvetica-Bold", size: 15.0)!,
NSAttributedStringKey.foregroundColor: UIColor.black] as [NSAttributedStringKey: Any]
//second text
let attributedString = NSMutableAttributedString(string: "\t"+String(places[indexPath.row].distance!)+" miles", attributes: [NSAttributedStringKey.font: UIFont(name: "Helvetica-Bold", size: 8.0)!,NSAttributedStringKey.foregroundColor: UIColor.black])
let myParagraphStyle = NSMutableParagraphStyle()
myParagraphStyle.alignment = .right
myParagraphStyle.tabStops = [
NSTextTab(textAlignment: .right, location: 300, options: [:]),
]
let attributedStringtitle = NSMutableAttributedString(string: places[indexPath.row].title!, attributes: attributestitle)
//adding the right alignment to the second text alone
attributedString.addAttributes([.paragraphStyle: myParagraphStyle], range: NSRange(location: 0, length: attributedString.length))
//combining two texts with different alignments.
let combination = NSMutableAttributedString()
combination.append(attributedStringtitle)
combination.append(attributedString)
cell.textLabel?.attributedText = combination
return cell;
}

Resources