I have been talking quite a lot in the past about how to customize text in your app to improve the UI of your applications. Before iOS 6, Core Text was the only available option for developers. Although a great framework, Core Text is not a very straightforward tool to use. You can check our Core Text tutorial in Objective-C here. In iOS 6, Apple introduced NSAttributedString. You can check a couple of posts about this topic here and here.

Core Text still remains the way to go for some specific cases that we will see later butNSAttributedString brings less hassle so, if possible, you should adopt it as a your first option. Then, on early June 2014, Apple introduced Swift. In this tutorial, we will build a project using Swift and NSAttributedString.

First, let me tell you more about some Cocoa classes that give you easy access to text customization. NSAttributedString allows you to customize the text attributes ofUILabelUIButtonUIPickerView, and UITableViewCell.

To use these properties, you just have to add any object of type UILabelUIButton,UIPickerView or UITableViewCell to your project and assign anNSAttributedString. For example, for a UILabel object, you would do the following:

labelName.attributedText = attributedString

Let’s build an example

Let’s write some code to see how to create attributed strings using Swift.

Launch Xcode and create a new Single-View Application project. Name it AttributedStringExample. Open the ViewController.swift file and edit the viewDidLoad()method as follows:

override func viewDidLoad() {
    super.viewDidLoad()
    if let titleFont = UIFont(name: "Copperplate", size: 50.0)  {
        let shadow : NSShadow = NSShadow()
        shadow.shadowOffset = CGSizeMake(-2.0, -2.0)

        let attributes = [
        NSFontAttributeName : titleFont,
        NSUnderlineStyleAttributeName : 1,
        NSForegroundColorAttributeName : UIColor.whiteColor(),
        NSTextEffectAttributeName : NSTextEffectLetterpressStyle, 
        NSStrokeWidthAttributeName : 3.0,
        NSShadowAttributeName : shadow]

        var title = NSAttributedString(string: "NSAttributedString", attributes: attributes) //1

        var label = UILabel(frame: CGRectMake(((self.view.bounds.size.width - title.size().width) / 2.0), 40.0, title.size().width, title.size().height)) //2
        label.attributedText = title //3
        view.addSubview(label) //4
    }
}

Here, we create the attributed string with the attributes in Line 1. In this particular case, we set the font and the size, text effect, color, shadow and underline attribute.

Line 2 instantiates a label and Line 3 sets the attributed string to the label. Finally (Line 4), we add the label as a subview of the viewcontroller view. I also changed to blue the background color of the view from the attributes Inspector in Interface Builder. Now, just build and run and you should see the following result:

title

This example shows how to create an attributed string and how to assign it to theattributedText property from a UILabel. Easy, right? But you may wonder, which attributes can I apply? Let’s check them out, one by one.

Character Attributes

Let’s check the character attributes currently available that you can apply to your text:

NSFontAttributeName

This allows you to change the font of your text. If not specified otherwise, default is 12-point Helvetica(Neue).

NSParagraphStyleAttributeName

This allows you to apply multiple attributes (such as alignment, tab stops and line break mode) to a range of text (aka paragraph).

NSForegroundColorAttributeName

The color of the text during rendering (black, by default).
The image below shows an example with red foreground.

title

NSBackgroundColorAttributeName

The color of the background area behind the text (no color, by default). Here, an example with yellow background in the image below.

title

NSLigatureAttributeName

Ligatures cause specific character combinations to be rendered using a single custom glyph that corresponds to those characters. The default value is 1, indicating the use of ligatures. You can specify no ligatures with value 0.
The following image shows the difference between setting a text with ligature attribute 0 (top text) and 1 (bottom text). Pay attention to the ff in caffeteria, the ffi in ufficiale and the ffl in affluente. They all belong to the f-ligatures type and they solve the unatractive collision between elements of the neighboring characters (the hook and crossbar of a double f or the hook of the f and the dot of the i).

title

NSKernAttributeName

Kern specifies the space between specific characters and it’s font-dependent. The default value is 0, which means no kerning. Any other number will specify the number of points between characters.

The following image shows the difference between setting a text with kern attribute value 10 (top text) and 0 (bottom text).

title

NSStrikethroughStyleAttributeName

The value of this attribute indicates wether the text is crossed out (strikethrough). Default value is none but you can specify several values to cross out the text with different styles.
The following example shows the result of applying different values of this property.

title

NSUnderlineStyleAttributeName

The value of this attribute indicates wether the text is rendered with a line under. The default value is none, but you can specify different values of underlining matching the same styles as for the strikethrough style.

title

NSStrokeColorAttributeName

This UIColor describes the outline color of the text. The default value is the same UIColor defined as the text foreground.

NSStrokeWidthAttributeName

This value represent the amount to change the stroke width. By default is 0, for no additional changes. A positive value will change the stroke width alone, a negative value will stroke and fill the text.

Find an example in the image below.

title

NSShadowAttributeName

This attribute allows you to add shadow to your text. Default value is nil, which mean, no shadow. Find an example in the image below.

title

NSTextEffectAttributeName

Use this attribute to specify a text effect. By default the value of this property is nil, indicating no text effect.

NSAttachmentAttributeName

The value of this attribute is an NSTextAttachment object. The default value of this property is nil, indicating no attachment.

NSLinkAttributeName

The value of this attribute is an NSURL or and NSString object. The default value of this property is nil, indicating no link.

NSBaselineOffsetAttributeName

This attribute indicates the character’s offset from the baseline, expressed in points. The baseline is the imaginary line upon which a line of text rests. The default value is 0.
The baseline for the text below is the red line.

title

NSUnderlineColorAttributeName

This attribute indicates the color of the line underneath the text. The default value coincides with the foreground color.
Find an example with a green double line in the image below.
title

NSStrikethroughColorAttributeName

This attribute indicates the color of the cross out line. The default value is the same as the foreground color.
Find an example with a red line in the image below.

title

NSObliquenessAttributeName

This attribute indicates the skew to be applied to glyphs. The default value is 0, meaning no skew. A positive value will lean the text towards the right, a negative value will lean it towards the left.
This attribute allows you to create your own italic version for a typeface that doesn’t have one. However, before you create your own, think if there might be a reason why the font doesn’t have the oblique version. Find an example using ‘Academy Engraved LET’ using a skew value of 1.

title

NSExpansionAttributeName

This attribute indicates the log of the expansion factor to be applied to glyphs. Default value is 0, no expansion. Use a positive value to enlarge and a negative value to shrink the text.
The following image shows the difference between setting a text with expansion factor 0 (text at the top) and 1 (text at the bottom).

title

NSWritingDirectionAttributeName

This attribute can help you write text from Left-to-Right and from Right-to-Left. You can also embed text in a text with a different writing direction and override the inherent directionality of characters.

NSVerticalGlyphFormAttributeName

This attribute indicates with value 0 horizontal text and with value 1 vertical text. In iOS, horizontal text is always used and specifying a different value is undefined. That means that you should not be using this attribute in iOS.

These are all the attributes offered by Apple that you can apply to the text in your apps. You can add or remove attributes to a particular range of characters usingNSMutableAttributedString combining chunks of text with different attributes. Here an example combining different styles:

title

NSAttributedString limitations

There are a couple of things that I’m aware of that are still not possible to do with attributed strings:

  1. If you need to render text vertically, attributed strings don’t seem to offer this solution just yet.
  2. If you want to draw into a shape other than a rectangle, you will still have to use Core Text.
  3. If you want to render your text on a non-horizontal line (such as a curved line), you will probably have to pick either Core Text or a CATextLayer.

However, Apple is adding more and more attributes to make it easier for us to render text and I’m happy to share with you all those improvements. I hope you found this post useful!

Happy coding!

Eva

Eva Diaz-Santana (@evdiasan) is cofounder of InvasiveCode. She develops iOS applications andteaches iOS development since 2008. She worked at Apple as Cocoa Architect and UX designer.

iOS Consulting | INVASIVECODE

iOS Training | INVASIVECODE

示例:

    private func getAttributeString(stringContent: String?, stringLabel: String?) -> NSMutableAttributedString {

        let string = stringLabel! + stringContent!

        let style = NSMutableParagraphStyle()

        style.alignment = .Center

        style.lineSpacing = 11

        let attributes = [

            NSFontAttributeName: UIFont.systemFontOfSize(15),

            NSParagraphStyleAttributeName: style

        ]

        let attributedString = NSMutableAttributedString(string: string, attributes: attributes)

        attributedString.setAttributes([NSFontAttributeName: UIFont.boldSystemFontOfSize(15)], range: NSMakeRange(0, stringLabel!.characters.count))

        

        return attributedString

    }

    

    private func applyWholeStringParagraphStyle(attributedStringTemp: NSMutableAttributedString) {

        let paragraphStyle = NSMutableParagraphStyle()

        paragraphStyle.lineSpacing = 10.5

        attributedStringTemp.addAttribute(NSParagraphStyleAttributeName, value: paragraphStyle, range: NSMakeRange(0, attributedStringTemp.length-1))

    }