[Updated to Swift 2.0/iOS9 9/30/15 SJL]
Sometimes you want to be fancy with your strings. For most uses, a basic string works well. Normal strings have no character or paragraph formatting. They rely on the properties of the control to format them. The system only formats the full string, not parts of it. For formatting a part of a string, you need an attributed string which specifies parts of the string formatted in different ways. In this lesson we’ll learn how to work in attributed strings in Swift.
Set Up A Project
In Xcode open a new project with Command-Shift-N. Use an iOS Application of a Single View Template. Add one label and three buttons looking like this:
Open the assistant editor, set to Automatic so the ViewController.swift file appears. Control-drag from the label to the code in the ViewController class. Make an outlet called myLabel. Drag from the ChalkDuster button to the code. Make an action named myFontButton. From the circle next to the code click-drag from the circle to the button named Georgia until the button highlights. Release the button, do the same from the code to the button titled AmericanTypewriter-Bold.
Close the assistant editor, and go over to the ViewController.swift file. Remove the didRecieveMemoryWarning
method.
The class so far should look like this:
class ViewController: UIViewController { @IBOutlet weak var myLabel: UILabel! @IBAction func myFontButton(sender: UIButton) { } override func viewDidLoad() { super.viewDidLoad() }
Add the following two properties to the ViewController
class:
var myString = "I Love Pizza!" var myMutableString = NSMutableAttributedString()
We will need a string and attributed text string. I’m using a NSMutableAttributedString
so I can add attributes as we go along in the lesson. If you have only one time you set attributes, you can do that with a NSAttributedString
.
Initializing an Attributed String
in the viewDidLoad
method, add the following code:
myMutableString = NSMutableAttributedString( string: myString, attributes: [NSFontAttributeName:UIFont( name: "Georgia", size: 18.0)!]) //Add more attributes here //Apply to the label myLabel.attributedText = myMutableString
Line 1 initializes an attributed string with the string myString
and an attribute dictionary. Here we used an attribute named NSFontAttributeName
as the key, and a UIFont
object as the value. Build and run. You will see this in the label:
Some Things to do with Attributed Text
Once you make the attributed string you can change it as much as you want with the addAttribute
method. There are a lot of attributes to change. For a list of them, you can look here in Apple’s documentation. I’ll go through a few useful ones for examples.
Add the following below the Add attributes here
comment:
myMutableString.addAttribute(NSFontAttributeName, value: UIFont( name: "Chalkduster", size: 24.0)!, range: NSRange( location: 7, length: 5))
Just like the initializer, we use the NSFontAttributeName
attribute as our attribute and 24 point Chalkduster as our font. What is new is range
. An NSRange
is a struct used for sequential data, such as strings. It has a location and a length. In the case above the location is 7 and the length 5. If you do the counting, this is the word Pizza in our original string. This will change the font of Pizza to 24 point Chalkduster. Build and run
Next add this line under the last one:
myMutableString.addAttribute(NSFontAttributeName, value: UIFont( name: "AmericanTypewriter-Bold", size: 18.0)!, range: NSRange( location:2, length:4))
This time we change the font of the word Love to 18pt American Typewriter bold. Build and run:
Now add this under the previous two lines:
myMutableString.addAttribute(NSForegroundColorAttributeName, value: UIColor.redColor(), range: NSRange( location:2, length:4))
We change the font color to red on the word Love with the NSForegroundColorAttributeName
attribute . Build and run:
And now add these three lines under those:
myMutableString.addAttribute(NSFontAttributeName, value: UIFont( name: "Georgia", size: 36.0)!, range: NSRange( location: 0, length: 1)) myMutableString.addAttribute(NSStrokeColorAttributeName, value: UIColor.blueColor(), range: NSRange( location: 0, length: 1)) myMutableString.addAttribute(NSStrokeWidthAttributeName, value: 2, range: NSRange( location: 0, length: 1))
The first attribute we know already. We set 36pt Georgia to the word I. Line two using NSStrokeColorAttributeName
sets the color for the outline of the letter I to blue. The third attribute uses NSStrokeWidthAttributeName
to set a stroke width, giving us an outlined letter. Build and run this:
You can set the background as well, but be careful. Add this to the code under the last code:
let stringLength = NSString(string: myString).length myMutableString.addAttribute(NSBackgroundColorAttributeName, value: UIColor.greenColor(), range: NSRange( location: 0, length: stringLength)) myLabel.backgroundColor = UIColor.grayColor()
Our range this time will be the complete string. The first line gets the length of the string is a slightly odd way. String
has no length
property Where NSString
does. The last line is for better contrast of what is going to happen. The NSBackgroundColorAttributeName
attribute will change the background for the font to green, but it does not change the background for the view. Our label is gray, and our font background is green. Build and run:
The font background will be the height of the largest letter, and as long as the range specified. If the label is bigger than the text size, you will have two background colors.
Changing the Same Range
Nothing says you cannot change a range once you added it. Change the myFontButton
to
@IBAction func myFontButton(sender: UIButton) { myMutableString.addAttribute(NSFontAttributeName, value: UIFont( name: sender.titleLabel!.text!, size: 24.0)!, range: NSRange( location: 7, length: 5)) myLabel.attributedText = myMutableString }
In this code we take the title of the button and use it as a font name for the word Pizza. Build and run. Tap the Georgia button,
tap the American Typewriter Bold Button
Tap the Chalkduster Button.
This is just the start of what you can do with attributed text. In the next lesson we’ll apply it to more labels and the UIPickerView
— Sort of.
The Whole Code
// // ViewController.swift // SwiftAttributedString // // Created by Steven Lipton on 10/18/14. // Copyright (c) 2014 MakeAppPie.Com. All rights reserved. // import UIKit class ViewController: UIViewController { @IBOutlet weak var myLabel: UILabel! @IBAction func myFontButton(sender: UIButton) { myMutableString.addAttribute(NSFontAttributeName, value: UIFont( name: sender.titleLabel!.text!, size: 24.0)!, range: NSRange( location: 7, length: 5)) myLabel.attributedText = myMutableString } var myString = "I Love Pizza!" var myMutableString = NSMutableAttributedString() override func viewDidLoad() { super.viewDidLoad() //Initialize the mutable string myMutableString = NSMutableAttributedString( string: myString, attributes: [NSFontAttributeName: UIFont(name: "Georgia", size: 18.0)!]) //Add more attributes here: myMutableString.addAttribute(NSFontAttributeName, value: UIFont( name: "Chalkduster", size: 24.0)!, range: NSRange( location: 7, length: 5)) myMutableString.addAttribute(NSFontAttributeName, value: UIFont( name: "AmericanTypewriter-Bold", size: 18.0)!, range: NSRange( location:2, length:4)) myMutableString.addAttribute(NSForegroundColorAttributeName, value: UIColor.redColor(), range: NSRange( location:2, length:4)) myMutableString.addAttribute(NSFontAttributeName, value: UIFont( name: "Georgia", size: 36.0)!, range: NSRange( location: 0, length: 1)) myMutableString.addAttribute(NSStrokeColorAttributeName, value: UIColor.blueColor(), range: NSRange( location: 0, length: 1)) myMutableString.addAttribute(NSStrokeWidthAttributeName, value: 2, range: NSRange( location: 0, length: 1)) let stringLength = NSString(string: myString).length myMutableString.addAttribute(NSBackgroundColorAttributeName, value: UIColor.greenColor(), range: NSRange( location: 0, length: stringLength )) myLabel.backgroundColor = UIColor.grayColor() //Apply to the label myLabel.attributedText = myMutableString } }
Leave a comment