You want to be able to display rich formatted text in your UI
components without having to create a separate UI component per
attribute. For instance, you may want to display one sentence that
contains only one of its words written in bold, inside a UILabel
.
Construct an instance of the NSAttributedString
or the mutable variant of
it, the NSMutableAttributedString
,
and either set it as the text of a UI component like the UILabel
component through its special
attributed string property, or simply use the attributed string’s
built-in methods to draw the text on a canvas.
Rich text is a thing of legend! A lot of us programmers have had the requirement to display mixed-style strings in one line of text on our UI. For instance, in one line of text you may have to display straight and italic text together, where one word is italic and the rest of the words are regular text. Or you may have had to underline a word inside a sentence. For this, some of us had to use Web Views, but that is not the optimal solution because Web Views are quite slow in rendering their content, and that will definitely impact the performance of your app. In iOS 7, we can start using attributed strings. I don’t know what took Apple so long to introduce this feature to iOS, as Mac developers have been using attributed strings for a long time now!
Before we begin, I want to clearly show you what I mean by attributed strings, using Figure 1-69. Then we will set out on the journey to write the program to achieve exactly this.
Note
Just to be explicit, this text is rendered inside a
single instance of the UILabel
class.
So what do we see in this example? I’ll list the pieces:
- The text “iOS” with the following attributes:
Bold font with size of 60 points
Background color of black
Font color of red
- The text “SDK” with the following attributes:
Bold font with size of 60 points
White text color
Light-gray shadow
Red background color
The best way to construct attributed strings is to use the
initWithString:
method of the mutable
variant of the NSMutableAttributedString
class and pass an
instance of the NSString
to this
method. This will create our attributed string without any attributes.
Then, to assign attributes to different parts of the string, we
will use the setAttributes:range:
method of the NSMutableAttributedString
class. This method
takes in two parameters:
setAttributes
A dictionary whose keys are character attributes and the value of each key depends on the key itself. Here are the most important keys that you can set in this dictionary:
NSFontAttributeName
The value of this key is an instance of
UIFont
and defines the font for the specific range of your string.NSForegroundColorAttributeName
The value for this key is of type
UIColor
and defines the color for your text for the specific range of your string.NSBackgroundColorAttributeName
The value of this key is of type
UIColor
and defines the background color on which the specific range of your string has to be drawn.NSShadowAttributeName
The value of this key must be an instance of the
NSShadow
and defines the shadow that you want to use under the specific range of your string.
range
A value of type
NSRange
that defines the starting point and the length of characters to which you want to apply the attributes.
Note
To see all the different keys that you can pass to this method,
simply browse the Apple documentation online for the NSMutableAttributedString
class. I will not
put the direct URL to this documentation here as Apple may change the
URL at some point, but a simple search online will do the
trick.
We’ll break our example down into two dictionaries of attributes. The dictionary of attributes for the word “iOS” can be constructed in this way in code:
NSDictionary
*
attributesForFirstWord
=
@
{
NSFontAttributeName
:
[
UIFont
boldSystemFontOfSize
:
60.0f
],
NSForegroundColorAttributeName
:
[
UIColor
redColor
],
NSBackgroundColorAttributeName
:
[
UIColor
blackColor
]
};
And the word “SDK” will be constructed using the following attributes:
NSShadow
*
shadow
=
[[
NSShadow
alloc
]
init
];
shadow
.
shadowColor
=
[
UIColor
darkGrayColor
];
shadow
.
shadowOffset
=
CGSizeMake
(
4.0f
,
4.0f
);
NSDictionary
*
attributesForSecondWord
=
@
{
NSFontAttributeName
:
[
UIFont
boldSystemFontOfSize
:
60.0f
],
NSForegroundColorAttributeName
:
[
UIColor
whiteColor
],
NSBackgroundColorAttributeName
:
[
UIColor
redColor
],
NSShadowAttributeName
:
shadow
};
Putting it together, we will get the following code that not only creates our label, but also sets its attributed text:
#import "ViewController.h"
@interface
ViewController
()
@property
(
nonatomic
,
strong
)
UILabel
*
label
;
@end
@implementation
ViewController
-
(
NSAttributedString
*
)
attributedText
{
NSString
*
string
=
@"iOS SDK"
;
NSMutableAttributedString
*
result
=
[[
NSMutableAttributedString
alloc
]
initWithString:
string
];
NSDictionary
*
attributesForFirstWord
=
@
{
NSFontAttributeName
:
[
UIFont
boldSystemFontOfSize
:
60.0f
],
NSForegroundColorAttributeName
:
[
UIColor
redColor
],
NSBackgroundColorAttributeName
:
[
UIColor
blackColor
]
};
NSShadow
*
shadow
=
[[
NSShadow
alloc
]
init
];
shadow
.
shadowColor
=
[
UIColor
darkGrayColor
];
shadow
.
shadowOffset
=
CGSizeMake
(
4.0f
,
4.0f
);
NSDictionary
*
attributesForSecondWord
=
@
{
NSFontAttributeName
:
[
UIFont
boldSystemFontOfSize
:
60.0f
],
NSForegroundColorAttributeName
:
[
UIColor
whiteColor
],
NSBackgroundColorAttributeName
:
[
UIColor
redColor
],
NSShadowAttributeName
:
shadow
};
/* Find the string "iOS" in the whole string and sets its attribute */
[
result
setAttributes
:
attributesForFirstWord
range:
[
string
rangeOfString
:
@"iOS"
]];
/* Do the same thing for the string "SDK" */
[
result
setAttributes
:
attributesForSecondWord
range:
[
string
rangeOfString
:
@"SDK"
]];
return
[[
NSAttributedString
alloc
]
initWithAttributedString
:
result
];
}
-
(
void
)
viewDidLoad
{
[
super
viewDidLoad
];
self
.
label
=
[[
UILabel
alloc
]
init
];
self
.
label
.
backgroundColor
=
[
UIColor
clearColor
];
self
.
label
.
attributedText
=
[
self
attributedText
];
[
self
.
label
sizeToFit
];
self
.
label
.
center
=
self
.
view
.
center
;
[
self
.
view
addSubview
:
self
.
label
];
}
@end
Get iOS 7 Programming Cookbook now with the O’Reilly learning platform.
O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.