How do you use NSAttributedString? How do you use NSAttributedString? ios ios

How do you use NSAttributedString?


When building attributed strings, I prefer to use the mutable subclass, just to keep things cleaner.

That being said, here's how you create a tri-color attributed string:

NSMutableAttributedString *string = [[NSMutableAttributedString alloc] initWithString:@"firstsecondthird"];[string addAttribute:NSForegroundColorAttributeName value:[UIColor redColor] range:NSMakeRange(0,5)];[string addAttribute:NSForegroundColorAttributeName value:[UIColor greenColor] range:NSMakeRange(5,6)];[string addAttribute:NSForegroundColorAttributeName value:[UIColor blueColor] range:NSMakeRange(11,5)];

typed in a browser. caveat implementor

Obviously you're not going to hard-code in the ranges like this. Perhaps instead you could do something like:

NSDictionary *wordToColorMapping = ....;  //an NSDictionary of NSString => UIColor pairsNSMutableAttributedString *string = [[NSMutableAttributedString alloc] initWithString:@""];for (NSString *word in wordToColorMapping) {  UIColor *color = [wordToColorMapping objectForKey:word];  NSDictionary *attributes = [NSDictionary dictionaryWithObject:color forKey:NSForegroundColorAttributeName];  NSAttributedString *subString = [[NSAttributedString alloc] initWithString:word attributes:attributes];  [string appendAttributedString:subString];  [subString release];}//display string


The question is already answered... but I wanted to show how to add shadow and change the font with NSAttributedString as well, so that when people search for this topic they won't have to keep looking.

#define FONT_SIZE 20#define FONT_HELVETICA @"Helvetica-Light"#define BLACK_SHADOW [UIColor colorWithRed:40.0f/255.0f green:40.0f/255.0f blue:40.0f/255.0f alpha:0.4f]NSString*myNSString = @"This is my string.\nIt goes to a second line.";                NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init];               paragraphStyle.alignment = NSTextAlignmentCenter;             paragraphStyle.lineSpacing = FONT_SIZE/2;                     UIFont * labelFont = [UIFont fontWithName:FONT_HELVETICA size:FONT_SIZE];                   UIColor * labelColor = [UIColor colorWithWhite:1 alpha:1];                       NSShadow *shadow = [[NSShadow alloc] init];                 [shadow setShadowColor : BLACK_SHADOW];                [shadow setShadowOffset : CGSizeMake (1.0, 1.0)];            [shadow setShadowBlurRadius : 1];NSAttributedString *labelText = [[NSAttributedString alloc] initWithString : myNSString                      attributes : @{   NSParagraphStyleAttributeName : paragraphStyle,             NSKernAttributeName : @2.0,             NSFontAttributeName : labelFont,  NSForegroundColorAttributeName : labelColor,           NSShadowAttributeName : shadow }];

Here is a Swift version...

Warning! This works for 4s.

For 5s you have to change all of the the Float values to Double values (because the compiler isn't working correctly yet)

Swift enum for font choice:

enum FontValue: Int {    case FVBold = 1 , FVCondensedBlack, FVMedium, FVHelveticaNeue, FVLight, FVCondensedBold, FVLightItalic, FVUltraLightItalic, FVUltraLight, FVBoldItalic, FVItalic}

Swift array for enum access (needed because enum can't use '-'):

func helveticaFont (index:Int) -> (String) {    let fontArray = [    "HelveticaNeue-Bold",    "HelveticaNeue-CondensedBlack",    "HelveticaNeue-Medium",    "HelveticaNeue",    "HelveticaNeue-Light",    "HelveticaNeue-CondensedBold",    "HelveticaNeue-LightItalic",    "HelveticaNeue-UltraLightItalic",    "HelveticaNeue-UltraLight",    "HelveticaNeue-BoldItalic",    "HelveticaNeue-Italic",    ]    return fontArray[index]}

Swift attributed text function:

func myAttributedText (myString:String, mySize: Float, myFont:FontValue) -> (NSMutableAttributedString) {    let shadow = NSShadow()    shadow.shadowColor = UIColor.textShadowColor()    shadow.shadowOffset = CGSizeMake (1.0, 1.0)    shadow.shadowBlurRadius = 1    let paragraphStyle = NSMutableParagraphStyle.alloc()    paragraphStyle.lineHeightMultiple = 1    paragraphStyle.lineBreakMode = NSLineBreakMode.ByWordWrapping    paragraphStyle.alignment = NSTextAlignment.Center    let labelFont = UIFont(name: helveticaFont(myFont.toRaw()), size: mySize)    let labelColor = UIColor.whiteColor()    let myAttributes :Dictionary = [NSParagraphStyleAttributeName : paragraphStyle,                                              NSKernAttributeName : 3, // (-1,5)                                              NSFontAttributeName : labelFont,                                   NSForegroundColorAttributeName : labelColor,                                            NSShadowAttributeName : shadow]    let myAttributedString = NSMutableAttributedString (string: myString, attributes:myAttributes)    // add new color     let secondColor = UIColor.blackColor()    let stringArray = myString.componentsSeparatedByString(" ")    let firstString: String? = stringArray.first    let letterCount = countElements(firstString!)    if firstString {        myAttributedString.addAttributes([NSForegroundColorAttributeName:secondColor], range:NSMakeRange(0,letterCount))    }    return  myAttributedString}

first and last extension used for finding ranges in a string array:

extension Array {    var last: T? {        if self.isEmpty {            NSLog("array crash error - please fix")            return self [0]        } else {            return self[self.endIndex - 1]        }    }}extension Array {    var first: T? {        if self.isEmpty {            NSLog("array crash error - please fix")            return self [0]        } else {            return self [0]        }    }}

new colors:

extension UIColor {    class func shadowColor() -> UIColor {        return UIColor(red: 0.0/255.0, green: 0.0/255.0, blue: 0.0/255.0, alpha: 0.3)    }    class func textShadowColor() -> UIColor {        return UIColor(red: 50.0/255.0, green: 50.0/255.0, blue: 50.0/255.0, alpha: 0.5)    }    class func pastelBlueColor() -> UIColor {        return UIColor(red: 176.0/255.0, green: 186.0/255.0, blue: 255.0/255.0, alpha: 1)    }    class func pastelYellowColor() -> UIColor {        return UIColor(red: 255.0/255.0, green: 238.0/255.0, blue: 140.0/255.0, alpha: 1)    }}

my macro replacement:

enum MyConstants: Float {    case CornerRadius = 5.0}

my button maker w/attributed text:

func myButtonMaker (myView:UIView) -> UIButton {    let myButton = UIButton.buttonWithType(.System) as UIButton    myButton.backgroundColor = UIColor.pastelBlueColor()    myButton.showsTouchWhenHighlighted = true;    let myCGSize:CGSize = CGSizeMake(100.0, 50.0)    let myFrame = CGRectMake(myView.frame.midX - myCGSize.height,myView.frame.midY - 2 * myCGSize.height,myCGSize.width,myCGSize.height)    myButton.frame = myFrame    let myTitle = myAttributedText("Button",20.0,FontValue.FVLight)    myButton.setAttributedTitle(myTitle, forState:.Normal)    myButton.layer.cornerRadius = myButton.bounds.size.width / MyConstants.CornerRadius.toRaw()    myButton.setTitleColor(UIColor.whiteColor(), forState: .Normal)    myButton.tag = 100    myButton.bringSubviewToFront(myView)    myButton.layerGradient()    myView.addSubview(myButton)    return  myButton}

my UIView/UILabel maker w/attributed text, shadow, and round corners:

func myLabelMaker (myView:UIView) -> UIView {    let myFrame = CGRectMake(myView.frame.midX / 2 , myView.frame.midY / 2, myView.frame.width/2, myView.frame.height/2)    let mylabelFrame = CGRectMake(0, 0, myView.frame.width/2, myView.frame.height/2)    let myBaseView = UIView()    myBaseView.frame = myFrame    myBaseView.backgroundColor = UIColor.clearColor()    let myLabel = UILabel()    myLabel.backgroundColor=UIColor.pastelYellowColor()    myLabel.frame = mylabelFrame    myLabel.attributedText = myAttributedText("This is my String",20.0,FontValue.FVLight)    myLabel.numberOfLines = 5    myLabel.tag = 100    myLabel.layer.cornerRadius = myLabel.bounds.size.width / MyConstants.CornerRadius.toRaw()    myLabel.clipsToBounds = true    myLabel.layerborders()    myBaseView.addSubview(myLabel)    myBaseView.layerShadow()    myBaseView.layerGradient()    myView.addSubview(myBaseView)    return myLabel}

generic shadow add:

func viewshadow<T where T: UIView> (shadowObject: T){    let layer = shadowObject.layer    let radius = shadowObject.frame.size.width / MyConstants.CornerRadius.toRaw();    layer.borderColor = UIColor.whiteColor().CGColor    layer.borderWidth = 0.8    layer.cornerRadius = radius    layer.shadowOpacity = 1    layer.shadowRadius = 3    layer.shadowOffset = CGSizeMake(2.0,2.0)    layer.shadowColor = UIColor.shadowColor().CGColor}

view extension for view style:

extension UIView {    func layerborders() {        let layer = self.layer        let frame = self.frame        let myColor = self.backgroundColor        layer.borderColor = myColor.CGColor        layer.borderWidth = 10.8        layer.cornerRadius = layer.borderWidth / MyConstants.CornerRadius.toRaw()    }    func layerShadow() {        let layer = self.layer        let frame = self.frame        layer.cornerRadius = layer.borderWidth / MyConstants.CornerRadius.toRaw()        layer.shadowOpacity = 1        layer.shadowRadius = 3        layer.shadowOffset = CGSizeMake(2.0,2.0)        layer.shadowColor = UIColor.shadowColor().CGColor    }    func layerGradient() {        let layer = CAGradientLayer()        let size = self.frame.size        layer.frame.size = size        layer.frame.origin = CGPointMake(0.0,0.0)        layer.cornerRadius = layer.bounds.size.width / MyConstants.CornerRadius.toRaw();        var color0 = CGColorCreateGenericRGB(250.0/255, 250.0/255, 250.0/255, 0.5)        var color1 = CGColorCreateGenericRGB(200.0/255, 200.0/255, 200.0/255, 0.1)        var color2 = CGColorCreateGenericRGB(150.0/255, 150.0/255, 150.0/255, 0.1)        var color3 = CGColorCreateGenericRGB(100.0/255, 100.0/255, 100.0/255, 0.1)        var color4 = CGColorCreateGenericRGB(50.0/255, 50.0/255, 50.0/255, 0.1)        var color5 = CGColorCreateGenericRGB(0.0/255, 0.0/255, 0.0/255, 0.1)        var color6 = CGColorCreateGenericRGB(150.0/255, 150.0/255, 150.0/255, 0.1)        layer.colors = [color0,color1,color2,color3,color4,color5,color6]        self.layer.insertSublayer(layer, atIndex: 2)    }}

the actual view did load function:

func buttonPress (sender:UIButton!) {    NSLog("%@", "ButtonPressed")}override func viewDidLoad() {    super.viewDidLoad()    let myLabel = myLabelMaker(myView)    let myButton = myButtonMaker(myView)    myButton.addTarget(self, action: "buttonPress:", forControlEvents:UIControlEvents.TouchUpInside)    viewshadow(myButton)    viewshadow(myLabel)}


I think, it is a very convenient way to use regular expressions to find a range for applying attributes. This is how I did it:

NSMutableAttributedString *goodText = [[NSMutableAttributedString alloc] initWithString:articleText];NSRange range = [articleText rangeOfString:@"\\[.+?\\]" options:NSRegularExpressionSearch|NSCaseInsensitiveSearch];if (range.location != NSNotFound) {    [goodText addAttribute:NSFontAttributeName value:[UIFont fontWithName:@"Georgia" size:16] range:range];    [goodText addAttribute:NSForegroundColorAttributeName value:[UIColor brownColor] range:range];}NSString *regEx = [NSString stringWithFormat:@"%@.+?\\s", [self.article.titleText substringToIndex:0]];range = [articleText rangeOfString:regEx options:NSRegularExpressionSearch|NSCaseInsensitiveSearch];if (range.location != NSNotFound) {    [goodText addAttribute:NSFontAttributeName value:[UIFont fontWithName:@"Georgia-Bold" size:20] range:range];    [goodText addAttribute:NSForegroundColorAttributeName value:[UIColor blueColor] range:range];}[self.textView setAttributedText:goodText];

I was searching for a list of available attributes and didn't find them here and in a class reference's first page. So I decided to post here information on that.

Standard Attributes

Attributed strings support the following standard attributes for text. If the key is not in the dictionary, then use the default values described below.

NSString *NSFontAttributeName;NSString *NSParagraphStyleAttributeName;NSString *NSForegroundColorAttributeName;NSString *NSUnderlineStyleAttributeName;NSString *NSSuperscriptAttributeName;NSString *NSBackgroundColorAttributeName;NSString *NSAttachmentAttributeName;NSString *NSLigatureAttributeName;NSString *NSBaselineOffsetAttributeName;NSString *NSKernAttributeName;NSString *NSLinkAttributeName;NSString *NSStrokeWidthAttributeName;NSString *NSStrokeColorAttributeName;NSString *NSUnderlineColorAttributeName;NSString *NSStrikethroughStyleAttributeName;NSString *NSStrikethroughColorAttributeName;NSString *NSShadowAttributeName;NSString *NSObliquenessAttributeName;NSString *NSExpansionAttributeName;NSString *NSCursorAttributeName;NSString *NSToolTipAttributeName;NSString *NSMarkedClauseSegmentAttributeName;NSString *NSWritingDirectionAttributeName;NSString *NSVerticalGlyphFormAttributeName;NSString *NSTextAlternativesAttributeName;

NSAttributedString programming guide

A full class reference is here.