I am trying to make a simple Coffee Calculator. I need to display the amount of coffee in grams. The "g" symbol for grams needs to be attached to my UILabel that I am using to display the amount. The numbers in the UILabel are changing dynamically with user input just fine, but I need to add a lower case "g" on the end of the string that is formatted differently from the updating numbers. The "g" needs to be attached to the numbers so that as the number size and position changes, the "g" "moves" with the numbers. I'm sure this problem has been solved before so a link in the right direction would be helpful as I've googled my little heart out.
I've searched through the documentation for an attributed string and I even downloded an "Attributed String Creator" from the app store, but the resulting code is in Objective-C and I am using Swift. What would be awesome, and probably helpful to other developers learning this language, is a clear example of creating a custom font with custom attributes using an attributed string in Swift. The documentation for this is very confusing as there is not a very clear path on how to do so. My plan is to create the attributed string and add it to the end of my coffeeAmount string.
var coffeeAmount: String = calculatedCoffee + attributedText
Where calculatedCoffee is an Int converted to a string and "attributedText" is the lowercase "g" with customized font that I am trying to create. Maybe I'm going about this the wrong way. Any help is appreciated!
The best way to approach Attributed Strings on iOS is by using the built-in Attributed Text editor in the interface builder and avoid uneccessary hardcoding NSAtrributedStringKeys in your source files.
You can later dynamically replace placehoderls at runtime by using this extension:
Add a storyboard label with attributed text looking like this.
Then you simply update the value each time you need like this:
Make sure to save into initalAttributedString the original value.
You can better understand this approach by reading this article: https://medium.com/mobile-appetite/text-attributes-on-ios-the-effortless-approach-ff086588173e
This answer has been updated for Swift 4.2.
Quick Reference
The general form for making and setting an attributed string is like this. You can find other common options below.
The rest of this post gives more detail for those who are interested.
Attributes
String attributes are just a dictionary in the form of
[NSAttributedString.Key: Any]
, whereNSAttributedString.Key
is the key name of the attribute andAny
is the value of some Type. The value could be a font, a color, an integer, or something else. There are many standard attributes in Swift that have already been predefined. For example:NSAttributedString.Key.font
, value: aUIFont
NSAttributedString.Key.foregroundColor
, value: aUIColor
NSAttributedString.Key.link
, value: anNSURL
orNSString
There are many others. See this link for more. You can even make your own custom attributes like:
key name:
NSAttributedString.Key.myName
, value: some Type.if you make an extension:
Creating attributes in Swift
You can declare attributes just like declaring any other dictionary.
Note the
rawValue
that was needed for the underline style value.Because attributes are just Dictionaries, you can also create them by making an empty Dictionary and then adding key-value pairs to it. If the value will contain multiple types, then you have to use
Any
as the type. Here is themultipleAttributes
example from above, recreated in this fashion:Attributed Strings
Now that you understand attributes, you can make attributed strings.
Initialization
There are a few ways to create attributed strings. If you just need a read-only string you can use
NSAttributedString
. Here are some ways to initialize it:If you will need to change the attributes or the string content later, you should use
NSMutableAttributedString
. The declarations are very similar:Changing an Attributed String
As an example, let's create the attributed string at the top of this post.
First create an
NSMutableAttributedString
with a new font attribute.If you are working along, set the attributed string to a
UITextView
(orUILabel
) like this:You don't use
textView.text
.Here is the result:
Then append another attributed string that doesn't have any attributes set. (Notice that even though I used
let
to declaremyString
above, I can still modify it because it is anNSMutableAttributedString
. This seems rather unSwiftlike to me and I wouldn't be surprised if this changes in the future. Leave me a comment when that happens.)Next we'll just select the "Strings" word, which starts at index
17
and has a length of7
. Notice that this is anNSRange
and not a SwiftRange
. (See this answer for more about Ranges.) TheaddAttribute
method lets us put the attribute key name in the first spot, the attribute value in the second spot, and the range in the third spot.Finally, let's add a background color. For variety, let's use the
addAttributes
method (note thes
). I could add multiple attributes at once with this method, but I will just add one again.Notice that the attributes are overlapping in some places. Adding an attribute doesn't overwrite an attribute that is already there.
Related
NSMutableAttributedString
but keep the attributesFurther Reading
Swift: xcode 6.1
I would highly recommend using a library for attributed strings. It makes it much easier when you want, for example, one string with four different colors and four different fonts. Here is my favorite. It is called SwiftyAttributes
If you wanted to make a string with four different colors and different fonts using SwiftyAttributes:
finalString
would show asSwift 2.0
Here is a sample:
OR
}
//Use it like below