Swift Mixed-Style Strings

Setting multiple styles in one string

iOS Applications have UIControls that are readily available to display the text of your choosing. You can set the size, color, shadow and background color of the particular string you want to display with ease. But what if you wanted to display one string and assign it multiple attributes for its size, color, shadow and background color like shown below.

This is a simple UILabel displaying an NSAttributedString

Starting from scratch

If you are in need of displaying a mixed-style string in one line of text, then I can show you one way you might want to implement this into your project. To start off open xCode and click on create a new xCode project and for the purpose of staying in sync you can choose single page application like the image below.

Click Next, add a product name and make sure language is Swift. Then click Next and Create.

Making the connection

The Next thing we will want to do is create a label and make sure it is properly connected. Start off by making sure you can see the Main.storyboard by clicking on the file (Arrow). Next click the Assistance Editor(Arrow) so now we can now see View and View Controller side by side. Add

@IBOutlet weak var label: UILabel!

in the class ViewController. Next find the UILabel Control by enabling show utilities
(Arrow 1), locating the Object Library (Arrow 2) and then initialize the Label in the view by dragging and dropping the Label from the Object Library onto Main.storyboards' View Controller Scene(Arrow 3).

Then to make the proper connection between the Label and View Controller we can drag the circle located in the View Controller(directly left of the IBOutlet we created in the view controller) and drop it over the Label in the View Controller Scene(Box).

A quick way to tell if your IBOutlet is connected is by looking here ...

located in the View Controller. If the circle to the left of the line declaring the IBOutlet is not solid like the one above then that means the outlet has not been connected yet. After the dragging and dropping, the circle will now change to a solid circle and that is just its way of letting us know the connection has been made. Now that the connection has been made we can start altering what the label will display in our ViewController class.

Setting one instance of UILabel to display text with different attributes

So now when are going to add some code to the view controller. We can simply change what the label will display in the view controller by telling the label what to display when the view controller loads. To do this we just add code in the overridden method viewDidLoad() like

 override func viewDidLoad() {
        super.viewDidLoad()
        label.textColor = UIColor.blueColor()
        label.text = "100000 lbs"
        view.addSubview(label)
}

but that only makes the UILabel display "100000 lbs" with a text color set to blue as displayed below.

We can change the size, font, and color of "100000 lbs" but we can only change the attributes for the entire string. What if we wanted to set "100000" with a different attributes than "lbs" like the image at the very start of this post.

Well here is how. First create function attributedText that takes in

func attributedText(first: String, second: String) -> NSAttributedString{
let string = first + second as NSString
let result = NSMutableAttributedString(string: string)
let attributesForFirstWord = [
        NSFontAttributeName : UIFont.boldSystemFontOfSize(60),
        NSForegroundColorAttributeName : UIColor.blueColor(),
        NSBackgroundColorAttributeName : UIColor.blackColor()
        ]
let shadow = NSShadow()
        shadow.shadowColor = UIColor.darkGrayColor()
        shadow.shadowOffset = CGSize(width: 4, height: 4)
let attributesForSecondWord = [
        NSFontAttributeName : UIFont.boldSystemFontOfSize(30),
        NSForegroundColorAttributeName : UIColor.whiteColor(),
        NSBackgroundColorAttributeName : UIColor.greenColor(),
        NSShadowAttributeName : shadow,
        ]

/* Find the string "100000" in the whole string and set its attribute */
result.setAttributes(attributesForFirstWord,
        range: string.rangeOfString(first))
        
/* Do the same thing for the string "lbs" */
result.setAttributes(attributesForSecondWord,
        range: string.rangeOfString(second))
        
return NSAttributedString(attributedString: result)


}

This function starts out by taking in two strings from its parameters first and second. Then combines the strings to make one NSString called string. We then convert our NSString named string into an NSMutableAttributedString named result. Using result we can add separate attributes to different words in the same string but to do so we need two variables to store them. So we let attributesForFirstWord and attributesForSecondWord be used to store the two different attributes. These couple lines of code

result.setAttributes(attributesForFirstWord,
        range: string.rangeOfString(first))    
   
result.setAttributes(attributesForSecondWord,
        range: string.rangeOfString(second))
 
return NSAttributedString(attributedString: result)

just sets the attributesForFirstWord for the range of the first and sets attributesForSecondWord for the range of second.

Now that we are all finished up with the function lets use it. So to implement this function we need to make our viewDidLoad() function look like

override func viewDidLoad() {
            super.viewDidLoad()
            label.attributedText = attributedText("100000", second: "lbs")

            view.addSubview(label)
    }

Then when you build and run you should have something looking like: