I am using TTTAttributedLabel (https://github.com/twotoasters/TTTAttributedLabel). Here I'm correctly getting the label with some clickable text.
I need to display my text like the username in above image(ie. without underline).How could I do that?
Try this code (sorry for formatting, written on phone...)
NSDictionary *linkAttributes = #{[NSNumber numberWithInt:kCTUnderlineStyleNone] : (id)kCTUnderlineStyleAttributeName};
self.label.linkAttributes = linkAttributes;
For swift 4.0
let LinkAttributes = NSMutableDictionary(dictionary: testLink.linkAttributes)
LinkAttributes[NSAttributedStringKey.underlineStyle] = NSNumber(value: false)
yourLabel.linkAttributes = LinkAttributes as NSDictionary as! [AnyHashable: Any]
if you are already having label with underline style and if you want to remove it programatically use the following code
let string = "your text"
let attributes: [NSAttributedString.Key: Any] = [
.font: UIFont.systemFont(ofSize: 13)
]
let attributedString = NSAttributedString(string: string,
attributes: attributes)
yourLabel.attributedText = attributedString
Related
I am appending a text on the end of a string that I have received by making the API Call in Xcode. Now, I want to add colour and make only the text "Tap to Read More" bold. Any suggestions on how can I achieve that? Would appreciate your help:)
self.content[i] = recievedData.title! + "\nTap to Read More "
let str = "Tap to Read More"
let attributes: [NSAttributedString.Key: Any] = [
.foregroundColor: UIColor.red,
]
let attributedQuote = NSAttributedString(string: str, attributes: attributes)
You can try NSAttributedString.
Example:
let str = "Tap to Read More"
// Create your attributed string
let attributes: [NSAttributedString.Key : Any] = [.foregroundColor : UIColor.red]
let attributedStr = NSAttributedString(string: str, attributes: attributes)
// Example for a UILabel
let lbl = UILabel()
lbl.attributedText = attributedStr
Doc on NSAttributedString: https://developer.apple.com/documentation/foundation/nsattributedstring
Scenario
I have a JSON feed where I get all this information about places in a city. The design looks like this (see attached image).
The design wants bolded text, URL text, different font size text. Sometimes the URL might not exist in the JSON feed.
Question
Which option is the best way to lay this out in a TableViewCell?
I'm thinking Option 3 is the easiest as I read that in Swift 4 you can use the new string literals. Concat all the strings with line breaks and then place them in a UITextView. But I don't think it supports formatted text.
Looking for feedback please
Updated: Based on the research below I figured out that you can solve this by using:
- NSAttributedStringKey
- NSAttributedString
- NSMutableAttributedString
First Step
I created a private function called generateEntry that returns an NSMutableAttributedString
private func generateEntry(bType: String, bTitle:String, bDescription:String, bUrl: String) -> NSMutableAttributedString {
// -- passed in parameters
let bookmarkType:String = bType
let bookmarkTitle:String = bTitle
let bookmarkDesc: String = bDescription
let bookmarkUrl: String = bUrl
// -- type
// Step 1 - you need to create the attribute for the string you want to change. Size, color, kern effect
// Step 2 - then you create a NSAttributedString and apply the attributes from the previous line
let bTypeAttribute = [NSAttributedStringKey.font: UIFont(name: "Arial", size: 14), NSAttributedStringKey.foregroundColor: UIColor.black, NSAttributedStringKey.kern: NSNumber(value: 0.5)]
let test: NSAttributedString = NSAttributedString(string: bookmarkType.uppercased() + ": ", attributes: bTypeAttribute as Any as? [NSAttributedStringKey : Any])
// -- title
let bTitleAttribute = [NSAttributedStringKey.font: UIFont(name: "Arial-Bold", size: 18), NSAttributedStringKey.foregroundColor: UIColor.black]
let testb: NSAttributedString = NSAttributedString(string: bookmarkTitle, attributes: bTitleAttribute as Any as? [NSAttributedStringKey : Any])
// -- description
let bDescriptionAttribute = [NSAttributedStringKey.font: UIFont(name: "Arial", size: 18), NSAttributedStringKey.foregroundColor: UIColor.black]
let testc: NSAttributedString = NSAttributedString(string: ": " + bookmarkDesc, attributes: bDescriptionAttribute as Any as? [NSAttributedStringKey : Any])
// -- url
let bURLAttribute = [NSAttributedStringKey.font: UIFont(name: "Arial-Italic", size: 18), NSAttributedStringKey.foregroundColor: UIColor.black]
let testd: NSAttributedString = NSAttributedString(string: bookmarkUrl, attributes: bURLAttribute as Any as? [NSAttributedStringKey : Any])
// combine the strings
let mutableAttributedString = NSMutableAttributedString()
mutableAttributedString.append(test)
mutableAttributedString.append(testb)
mutableAttributedString.append(testc)
mutableAttributedString.append(NSAttributedString(string: "\n"))
mutableAttributedString.append(testd)
return mutableAttributedString
}
Step 2
Then within my tableViewCell I can use this private method to generate the NSMutableAttributedString and apply it to my custom tableViewCell. But instead of using cell.descriptionLabel.text you need to make sure to use attributedText
let testText = generateEntry(bType: "Type", bTitle: "PLACE", bDescription: "A description...", bUrl: "URL")
cell.descriptionLabel?.attributedText = testText
just started swift 3 and I have problems with swift syntax.
i'm trying to display a simple NSAttributedString.
so 1st I set my attributes :
let attributeFontSaySomething : [String : AnyObject] = [NSFontAttributeName : UIFont.fontSaySomething()]
let attributeColorSaySomething : [String : AnyObject] = [NSForegroundColorAttributeName : UIColor.blue]
Then I create my string :
let attStringSaySomething = NSAttributedString(string: "Say something", attributes: self.attributeFontSaySomething)
What i would like to do is to create the string with my 2 attributes not only just one. But when i do :
let attStringSaySomething = NSAttributedString(string: "Say something", attributes: [self.attributeFontSaySomething, self.attributeColorSaySomething])
Xcode tells me I can't and want me to change this for a literal dictionary.
How can I create my string with the 2 attributes without using a NSMutableAttributedString ?
The main issue is that you are passing an array [attr.. , attr...] rather than one dictionary.
You need to merge the two dictionaries into one
let attributeFontSaySomething : [String : Any] = [NSFontAttributeName : UIFont.systemFont(ofSize: 12.0)]
let attributeColorSaySomething : [String : Any] = [NSForegroundColorAttributeName : UIColor.blue]
var attributes = attributeFontSaySomething
for (key, value) in attributeColorSaySomething {
attributes(value, forKey: key)
}
let attStringSaySomething = NSAttributedString(string: "Say something", attributes: attributes)
However it might be easier to create the dictionary literally:
let attributes : [String : Any] = [NSFontAttributeName : UIFont.systemFont(ofSize: 12.0), NSForegroundColorAttributeName : UIColor.blue]
Just create a single dictionary with both sets of attributes:
let attributes: [String:AnyObject] =
[NSFontAttributeName : UIFont.fontSaySomething(),
NSForegroundColorAttributeName : UIColor.blue]
And then use the dictionary with both key/value pairs when creating your attributed string.
There's no built-in mechanism in Swift for combining dictionaries, but you could add an override of the + operator if you wanted to be able to add dictionaries together (You'd have to work out what to do if both dictionaries contained the same key however.)
Use like this:
let attStringSaySomething = NSAttributedString.init(string: "Hello", attributes: [NSFontAttributeName: UIFont.systemFont(ofSize: 16), NSForegroundColorAttributeName:UIColor.black])
You can use this code for different attributes on different strings With Roboto font (For Roboto font use MDFRobotoFontLoader)
let yourAttributes = [NSForegroundColorAttributeName: UIColor.black, NSFontAttributeName: MDFRobotoFontLoader.sharedInstance().regularFont(ofSize: 20)]
let finalString = NSMutableAttributedString(string: "", attributes: yourAttributes)
let attributeStr = NSMutableAttributedString(string: "XYZGFDGii", attributes: yourAttributes)
finalString.append(attributeStr)
let yourOtherAttributes = [NSForegroundColorAttributeName: UIColor.red, NSFontAttributeName: MDFRobotoFontLoader.sharedInstance().regularFont(ofSize: 24)]
let partTwo = NSMutableAttributedString(string: "hfjghlkdhkjld", attributes: yourOtherAttributes)
finalString.append(partTwo)
This example uses Roboto font
Thanks for #vadian's answer
Update For Swift 4
let attributes : [NSAttributedStringKey : Any] = [NSAttributedStringKey(rawValue: NSAttributedStringKey.font.rawValue) : UIFont.systemFont(ofSize: 12.0), NSAttributedStringKey(rawValue: NSAttributedStringKey.foregroundColor.rawValue) : UIColor(hex:"4C0000")]
refreshControl.attributedTitle=NSAttributedString(string: "Refreshing...", attributes: attributes)
The problem is that you are inserting two dictionaries into a dictionary, what only expects [String: Any], not [[String: Any], [String: Any]] type.
You can do the following:
let attStringSaySomething = NSAttributedString(string: "Say something", attributes: [NSFontAttributeName : UIFont.fontSaySomething(), NSForegroundColorAttributeName : UIColor.blue])
You could also group the values into tuples instead of dictionaries, and insert them into your dictionary based on the key and value:
let attributeFontSaySomething = (key: NSFontAttributeName, value: UIFont.fontSaySomething())
let attributeColorSaySomething = (key: NSForegroundColorAttributeName, value: UIColor.blue)
let attStringSaySomething = NSAttributedString(string: "Say something", attributes: [attributeFontSaySomething.key : attributeFontSaySomething.value,attributeColorSaySomething.key : attributeColorSaySomething.value])
Some of the answers are out dated here, especially for Swift 4 and above, you can use something like:
let wholeString = "This is whole string"
let partToAttribute = "whole string"
let attributedMessage = NSMutableAttributedString(string: wholeString)
.highlightString(with: UIColor.blue, for: partToAttribute, isBackground: true)
.fontHighlightString(with: UIFont.makeBoldFont(size: 16), color: UIColor.white, for: partToAttribute)
titleLabel.attributedText = attributedMessage
So at the end, you apply 2 attributes which are highlightString and fontHighlightString
First you can initialise attributes by using
var myAttribute = [ NSAttributedString.Key.foregroundColor: UIColor.init(hexString: "#FFAEA9"), NSAttributedString.Key.font: UIFont(name: "Dubai-Medium", size: 16) ]
after that you can use it...
let myString = "Enter default amount"
let text = NSAttributedString(string: myString, attributes: myAttribute)
enterCustomAmount.setAttributedTitle(text, for: .normal)
I want to center and bold the title of my paragraph. So far I can make the title bold but I cant center it.
Here's my code:
let title = "Title of Paragraph"
let attrs = [NSFontAttributeName : UIFont.boldSystemFontOfSize(15)]
let boldString = NSMutableAttributedString(string:title, attributes:attrs)
let normalText = "Something here.............."
let attributedString = NSMutableAttributedString(string:normalText)
boldString.appendAttributedString(attributedString)
label.attributedText = boldString
I tried to add another attribue in attrs:
let attrs = [NSFontAttributeName : UIFont.boldSystemFontOfSize(15), NSTextAlignment: NSTextAlignment.Center]
I'm not sure if that's the correct way to center it, but it still gives an error "Type of expression is ambiguous without more context"
I've searched the error but it seems I still can't fix the problem
I think the problem is with the NSTextAlignment key that you are trying to add on the dictionary. It's type is Int which becomes ambiguous with the previous key that is a String so I guess that's why the compiler is complaining. Either way NSTextAlignment is not a valid key to be used on NSMutableAttributedString attributes initialiser.
Maybe you are looking for something like that:
let string = "Any String"
let style = NSMutableParagraphStyle()
style.alignment = .Center
let attributes = [
NSFontAttributeName: UIFont.boldSystemFontOfSize(15),
NSParagraphStyleAttributeName: style
]
let attributedString = NSMutableAttributedString(string: string, attributes: attributes)
Try a category on UILabel:
UILabel+boldText
func boldSubstring(substring: String) {
var range: NSRange = self.text!.rangeOfString(substring)
var attributedText: NSMutableAttributedString = NSMutableAttributedString(attributedString: self.attributedText)
attributedText.setAttributes([NSFontAttributeName: UIFont.boldSystemFontOfSize(self.font.pointSize)], range: range)
self.attributedText = attributedText
}
func centerAlginement(substring:String) {
var paragraphStyle: NSMutableParagraphStyle = NSMutableParagraphStyle.new
paragraphStyle.alignment = .Center
var attributedString: NSAttributedString = NSAttributedString.alloc(string: substring, attributes: [NSParagraphStyleAttributeName: paragraphStyle])
self.attributedText = attributedString
}
now you can use it in your view import category class to your view
myLabel.text = "DemoText"
myLabel.boldSubstring(myLabel.text)
myLabel.centerAlginement(myLabel.text)
I was wondering how can I print formated text from the keyboard keys. For example, I have a toolbar attached to the keyboard, I click "bold" on the keyboard and from there on every letter printed from the keyboard will now be bold. This is what I have but it does not work, String's don't seem to hold format.
func keyPressed(sender: AnyObject?) {
let button = sender as! UIButton
let title = button.titleForState(.Normal)
let attrs = [NSFontAttributeName : UIFont.boldSystemFontOfSize(15)]
let boldString = NSMutableAttributedString(string:title!, attributes:attrs)
(textDocumentProxy as UIKeyInput).insertText(boldString.string)
}
Strings don't hold format, you're right. You should manipulate your target directly, using NSAttributedString and attributedText to do so.
let str = "Hello, world!"
let attrs = [NSFontAttributeName: UIFont.systemFontOfSize(15)]
let attributedString = NSAttributedString(string: str, attributes: attrs)
yourTextView.attributedText = attributedString
Note that the specific thing you want to do is tricky, because attributed strings attach attributes (like bold) to parts of text and not "from there on every letter". So if you read out the current attributed string then try to modify the attributes at the caret without actually inserting anything, it won't work.
So, this won't work:
let existingAttributedString = yourTextView.attributedText.mutableCopy() as! NSMutableAttributedString
let newAttrs = [NSFontAttributeName: UIFont.boldSystemFontOfSize(15)]
let newAttributedString = NSAttributedString(string: "", attributes: newAttrs)
existingAttributedString.appendAttributedString(newAttributedString)
Whereas this will:
let existingAttributedString = yourTextView.attributedText.mutableCopy() as! NSMutableAttributedString
let newAttrs = [NSFontAttributeName: UIFont.boldSystemFontOfSize(15)]
let newAttributedString = NSAttributedString(string: " ", attributes: newAttrs)
existingAttributedString.appendAttributedString(newAttributedString)
The only difference is that the second example inserts a space, which is enough for iOS to attach attributes to.
That being said, if you're willing to change your approach so that users select existing text before hitting bold, that works great.