How do I make an attributed string using Swift? How do I make an attributed string using Swift? swift swift

How do I make an attributed string using Swift?


enter image description here

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.

// create attributed stringlet myString = "Swift Attributed String"let myAttribute = [ NSAttributedString.Key.foregroundColor: UIColor.blue ]let myAttrString = NSAttributedString(string: myString, attributes: myAttribute) // set attributed text on a UILabelmyLabel.attributedText = myAttrString

Text Color

let myAttribute = [ NSAttributedString.Key.foregroundColor: UIColor.blue ]

Background Color

let myAttribute = [ NSAttributedString.Key.backgroundColor: UIColor.yellow ]

Font

let myAttribute = [ NSAttributedString.Key.font: UIFont(name: "Chalkduster", size: 18.0)! ]

enter image description here

let myAttribute = [ NSAttributedString.Key.underlineStyle: NSUnderlineStyle.single.rawValue ]

enter image description here

let myShadow = NSShadow()myShadow.shadowBlurRadius = 3myShadow.shadowOffset = CGSize(width: 3, height: 3)myShadow.shadowColor = UIColor.graylet myAttribute = [ NSAttributedString.Key.shadow: myShadow ]

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], where NSAttributedString.Key is the key name of the attribute and Any 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:

  • key name: NSAttributedString.Key.font, value: a UIFont
  • key name: NSAttributedString.Key.foregroundColor, value: a UIColor
  • key name: NSAttributedString.Key.link, value: an NSURL or NSString

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:

    extension NSAttributedString.Key {    static let myName = NSAttributedString.Key(rawValue: "myCustomAttributeKey")}

Creating attributes in Swift

You can declare attributes just like declaring any other dictionary.

// single attributes declared one at a timelet singleAttribute1 = [ NSAttributedString.Key.foregroundColor: UIColor.green ]let singleAttribute2 = [ NSAttributedString.Key.backgroundColor: UIColor.yellow ]let singleAttribute3 = [ NSAttributedString.Key.underlineStyle: NSUnderlineStyle.double.rawValue ]// multiple attributes declared at oncelet multipleAttributes: [NSAttributedString.Key : Any] = [    NSAttributedString.Key.foregroundColor: UIColor.green,    NSAttributedString.Key.backgroundColor: UIColor.yellow,    NSAttributedString.Key.underlineStyle: NSUnderlineStyle.double.rawValue ]// custom attributelet customAttribute = [ NSAttributedString.Key.myName: "Some value" ]

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 the multipleAttributes example from above, recreated in this fashion:

var multipleAttributes = [NSAttributedString.Key : Any]()multipleAttributes[NSAttributedString.Key.foregroundColor] = UIColor.greenmultipleAttributes[NSAttributedString.Key.backgroundColor] = UIColor.yellowmultipleAttributes[NSAttributedString.Key.underlineStyle] = NSUnderlineStyle.double.rawValue

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:

// Initialize with a string onlylet attrString1 = NSAttributedString(string: "Hello.")// Initialize with a string and inline attribute(s)let attrString2 = NSAttributedString(string: "Hello.", attributes: [NSAttributedString.Key.myName: "A value"])// Initialize with a string and separately declared attribute(s)let myAttributes1 = [ NSAttributedString.Key.foregroundColor: UIColor.green ]let attrString3 = NSAttributedString(string: "Hello.", attributes: myAttributes1)

If you will need to change the attributes or the string content later, you should use NSMutableAttributedString. The declarations are very similar:

// Create a blank attributed stringlet mutableAttrString1 = NSMutableAttributedString()// Initialize with a string onlylet mutableAttrString2 = NSMutableAttributedString(string: "Hello.")// Initialize with a string and inline attribute(s)let mutableAttrString3 = NSMutableAttributedString(string: "Hello.", attributes: [NSAttributedString.Key.myName: "A value"])// Initialize with a string and separately declared attribute(s)let myAttributes2 = [ NSAttributedString.Key.foregroundColor: UIColor.green ]let mutableAttrString4 = NSMutableAttributedString(string: "Hello.", attributes: myAttributes2)

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.

let myAttribute = [ NSAttributedString.Key.font: UIFont(name: "Chalkduster", size: 18.0)! ]let myString = NSMutableAttributedString(string: "Swift", attributes: myAttribute )

If you are working along, set the attributed string to a UITextView (or UILabel) like this:

textView.attributedText = myString

You don't use textView.text.

Here is the result:

enter image description here

Then append another attributed string that doesn't have any attributes set. (Notice that even though I used let to declare myString above, I can still modify it because it is an NSMutableAttributedString. 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.)

let attrString = NSAttributedString(string: " Attributed Strings")myString.append(attrString)

enter image description here

Next we'll just select the "Strings" word, which starts at index 17 and has a length of 7. Notice that this is an NSRange and not a Swift Range. (See this answer for more about Ranges.) The addAttribute 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.

var myRange = NSRange(location: 17, length: 7) // range starting at location 17 with a lenth of 7: "Strings"myString.addAttribute(NSAttributedString.Key.foregroundColor, value: UIColor.red, range: myRange)

enter image description here

Finally, let's add a background color. For variety, let's use the addAttributes method (note the s). I could add multiple attributes at once with this method, but I will just add one again.

myRange = NSRange(location: 3, length: 17)let anotherAttribute = [ NSAttributedString.Key.backgroundColor: UIColor.yellow ]myString.addAttributes(anotherAttribute, range: myRange)

enter image description here

Notice that the attributes are overlapping in some places. Adding an attribute doesn't overwrite an attribute that is already there.

Related

Further Reading


Swift uses the same NSMutableAttributedString that Obj-C does. You instantiate it by passing in the calculated value as a string:

var attributedString = NSMutableAttributedString(string:"\(calculatedCoffee)")

Now create the attributed g string (heh). Note: UIFont.systemFontOfSize(_) is now a failable initializer, so it has to be unwrapped before you can use it:

var attrs = [NSFontAttributeName : UIFont.systemFontOfSize(19.0)!]var gString = NSMutableAttributedString(string:"g", attributes:attrs)

And then append it:

attributedString.appendAttributedString(gString)

You can then set the UILabel to display the NSAttributedString like this:

myLabel.attributedText = attributedString


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:

let magenta = "Hello ".withAttributes([    .textColor(.magenta),    .font(.systemFont(ofSize: 15.0))    ])let cyan = "Sir ".withAttributes([    .textColor(.cyan),    .font(.boldSystemFont(ofSize: 15.0))    ])let green = "Lancelot".withAttributes([    .textColor(.green),    .font(.italicSystemFont(ofSize: 15.0))    ])let blue = "!".withAttributes([    .textColor(.blue),    .font(.preferredFont(forTextStyle: UIFontTextStyle.headline))    ])let finalString = magenta + cyan + green + blue

finalString would show as

Shows as image