Change the color of a link in an NSMutableAttributedString
Swift
Updated for Swift 4.2
Use linkTextAttributes
with a UITextView
textView.linkTextAttributes = [NSAttributedString.Key.foregroundColor: UIColor.green]
And in context:
let attributedString = NSMutableAttributedString(string: "The site is www.google.com.")
let linkRange = (attributedString.string as NSString).range(of: "www.google.com")
attributedString.addAttribute(NSAttributedString.Key.link, value: "https://www.google.com", range: linkRange)
let linkAttributes: [NSAttributedString.Key : Any] = [
NSAttributedString.Key.foregroundColor: UIColor.green,
NSAttributedString.Key.underlineColor: UIColor.lightGray,
NSAttributedString.Key.underlineStyle: NSUnderlineStyle.single.rawValue
]
// textView is a UITextView
textView.linkTextAttributes = linkAttributes
textView.attributedText = attributedString
Objective-C
Use linkTextAttributes
with a UITextView
textView.linkTextAttributes = @{NSForegroundColorAttributeName:[UIColor greenColor]};
Source: this answer
And from this post:
NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:@"This is an example by @marcelofabri_"];
[attributedString addAttribute:NSLinkAttributeName
value:@"username://marcelofabri_"
range:[[attributedString string] rangeOfString:@"@marcelofabri_"]];
NSDictionary *linkAttributes = @{NSForegroundColorAttributeName: [UIColor greenColor],
NSUnderlineColorAttributeName: [UIColor lightGrayColor],
NSUnderlineStyleAttributeName: @(NSUnderlineStyleSingle)};
// assume that textView is a UITextView previously created (either by code or Interface Builder)
textView.linkTextAttributes = linkAttributes; // customizes the appearance of links
textView.attributedText = attributedString;
textView.delegate = self;
Change NSAttributedString html links color
I found an answer for this in swift 4.0
termsAndPolicyTextView.linkTextAttributes = [NSAttributedString.Key.foregroundColor: UIColor.red]
Full code:
Note: I can't set multiple color in a single textView.
let attributedString = NSMutableAttributedString(string: termsAndPolicyText)
attributedString.addAttribute(NSAttributedString.Key.link,
value: "https://google.co.in",
range: (termsAndPolicyText as NSString).range(of: "Terms or service")
)
attributedString.addAttribute(NSAttributedString.Key.link,
value: "https://google.co.in", // Todo set our terms and policy link here
range: (termsAndPolicyText as NSString).range(of: "Privacy & Legal Policy")
)
attributedString.addAttributes([NSAttributedString.Key.foregroundColor: UIColor.NMSTextColor(with: 0.6)],
range: NSRange(location: 0, length: termsAndPolicyText.count))
termsAndPolicyTextView.linkTextAttributes = [NSAttributedString.Key.foregroundColor: UIColor.termstextViewTextColor()]
termsAndPolicyTextView.attributedText = attributedString
termsAndPolicyTextView.textAlignment = .center
}
Change links colors and underline color of html converted to AttributedString
If you are using a UITextView
, it would be enough to set the tintColor
to UIColor.red
and remove the following:
let attributes: [NSAttributedString.Key: AnyObject] = [NSAttributedString.Key.foregroundColor: UIColor.red]
attributedString?.addAttributes(attributes, range: NSRange.init(location: 0, length: attributedString?.length ?? 0))
so it would look like this:
public func htmlStyleAttributeText(text: String) -> NSMutableAttributedString? {
if let htmlData = text.data(using: .utf8) {
let options: [NSAttributedString.DocumentReadingOptionKey: Any] = [NSAttributedString.DocumentReadingOptionKey.documentType: NSAttributedString.DocumentType.html, NSAttributedString.DocumentReadingOptionKey.characterEncoding: String.Encoding.utf8.rawValue]
let attributedString = try? NSMutableAttributedString(data: htmlData, options: options, documentAttributes: nil)
return attributedString
}
return nil
}
//
textView.tintColor = .red
textView.attributedText = htmlStyleAttributeText(text: "random text <a href='http://www.google.com'>http://www.google.com </a> more random text")
Output:
How can you change the color of links in a UILabel?
For default NSAttributedString.Key.link color will be blue.
If you need custom colors for links you can set the attribute as NSAttributedString.Key.attachment instead of .link and set the foreground and underline colors like this:
let linkCustomAttributes = [NSAttributedString.Key.font: UIFont.systemFont(ofSize: 14),
NSAttributedString.Key.foregroundColor: UIColor.red,
NSAttributedString.Key.underlineColor: UIColor.magenta,
NSAttributedString.Key.underlineStyle: NSUnderlineStyle.single.rawValue,
NSAttributedString.Key.attachment: URL(string: "https://www.google.com")] as [NSAttributedString.Key : Any]
If you need to handle touches on links you can use this custom label class:
import UIKit
public protocol UILabelTapableLinksDelegate: NSObjectProtocol {
func tapableLabel(_ label: UILabelTapableLinks, didTapUrl url: String, atRange range: NSRange)
}
public class UILabelTapableLinks: UILabel {
private var links: [String: NSRange] = [:]
private(set) var layoutManager = NSLayoutManager()
private(set) var textContainer = NSTextContainer(size: CGSize.zero)
private(set) var textStorage = NSTextStorage() {
didSet {
textStorage.addLayoutManager(layoutManager)
}
}
public weak var delegate: UILabelTapableLinksDelegate?
public override var attributedText: NSAttributedString? {
didSet {
if let attributedText = attributedText {
textStorage = NSTextStorage(attributedString: attributedText)
findLinksAndRange(attributeString: attributedText)
} else {
textStorage = NSTextStorage()
links = [:]
}
}
}
public override var lineBreakMode: NSLineBreakMode {
didSet {
textContainer.lineBreakMode = lineBreakMode
}
}
public override var numberOfLines: Int {
didSet {
textContainer.maximumNumberOfLines = numberOfLines
}
}
public override init(frame: CGRect) {
super.init(frame: frame)
setup()
}
public required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
setup()
}
private func setup() {
isUserInteractionEnabled = true
layoutManager.addTextContainer(textContainer)
textContainer.lineFragmentPadding = 0
textContainer.lineBreakMode = lineBreakMode
textContainer.maximumNumberOfLines = numberOfLines
}
public override func layoutSubviews() {
super.layoutSubviews()
textContainer.size = bounds.size
}
private func findLinksAndRange(attributeString: NSAttributedString) {
links = [:]
let enumerationBlock: (Any?, NSRange, UnsafeMutablePointer<ObjCBool>) -> Void = { [weak self] value, range, isStop in
guard let strongSelf = self else { return }
if let value = value {
let stringValue = "\(value)"
strongSelf.links[stringValue] = range
}
}
attributeString.enumerateAttribute(.link, in: NSRange(0..<attributeString.length), options: [.longestEffectiveRangeNotRequired], using: enumerationBlock)
attributeString.enumerateAttribute(.attachment, in: NSRange(0..<attributeString.length), options: [.longestEffectiveRangeNotRequired], using: enumerationBlock)
}
public override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
guard let locationOfTouch = touches.first?.location(in: self) else {
return
}
textContainer.size = bounds.size
let indexOfCharacter = layoutManager.glyphIndex(for: locationOfTouch, in: textContainer)
for (urlString, range) in links where NSLocationInRange(indexOfCharacter, range) {
delegate?.tapableLabel(self, didTapUrl: urlString, atRange: range)
return
}
}
}
Setup label in your code:
customLabel.attributedText = <<Your attributed text with custom links>>
customLabel.delegate = self
Implement delegate:
extension YourClass: UILabelTapableLinksDelegate {
func tapableLabel(_ label: UILabelTapableLinks, didTapUrl url: String, atRange range: NSRange) {
print("didTapUrl: ", url)
}
}
Change string color with NSAttributedString?
There is no need for using NSAttributedString
. All you need is a simple label with the proper textColor
. Plus this simple solution will work with all versions of iOS, not just iOS 6.
But if you needlessly wish to use NSAttributedString
, you can do something like this:
UIColor *color = [UIColor redColor]; // select needed color
NSString *string = ... // the string to colorize
NSDictionary *attrs = @{ NSForegroundColorAttributeName : color };
NSAttributedString *attrStr = [[NSAttributedString alloc] initWithString:string attributes:attrs];
self.scanLabel.attributedText = attrStr;
Related Topics
How to Move to the Next Page in Facebook JSON Response Using iOS Sdk
Custom View Which Looks Like Uialertview
iOS - Uisplitviewcontroller with Storyboard - Multiple Master Views and Multiple Detail Views
Swiftui Transitions: Scale from Some Frame - Like iOS Homescreen Is Doing When Opening an App
iPhone Opengl Es 2.0 - Pixel Perfect Textures
How to Draw a Non-Rectangle Uitextview
How to Delete a Child from Firebase (Swift)
Create Ssl Connection Using Certificate
Property Cannot Be Found in Forward Class Object
A Server with the Specified Hostname Could Not Be Found
How to Represent Core Data Optional Scalars (Bool/Int/Double/Float) in Swift
How to Get Uitouch Location from Uigesturerecognizer
Push View Programmatically in Callback, Swiftui
How to Set the Tab Order in iOS
Unknown Class in Interface Builder
"Unable to Validate Your Application Error" While Uploading a New Version of iOS App
How to Programmatically Dismiss Uialertcontroller Without Any Buttons