Arun
Arun

Reputation: 3456

Applying different attributes for different portions of an NSAttributedstring

I know it is possible to apply attributes to an NSAttributedString.

But how can we apply different attributes to same attributed string.

for the string "This is an attributed text."

How can we set a particular attribute(background color or foreground color) to "This is" another attribute(background color or foreground color) to "an attributed text."

Is there any way to achieve this....?

Also is there any way to set the background color of an NSAttributedString in iOS?

Upvotes: 3

Views: 5833

Answers (2)

Atka
Atka

Reputation: 547

I am using the following extension to change "NSMutableAttributedString" colour and it did the trick nicely. It can be used as a template

extension NSMutableAttributedString {

    func changeColourOf(_ terms: [String], toThisColour termsColour:  UIColor, 
                        andForegroundColour fontColour: UIColor) {

        // Set your foreground Here
        addAttributes([NSAttributedString.Key.foregroundColor : fontColour], 
                      range: NSMakeRange(0, self.length))

        // Convert "NSMutableAttributedString" to a NSString  
        let string = self.string as NSString
    
        // Create a for loop for ther terms array
        for term in terms {
            // This will be the range of each term
            let underlineRange = string.range(of: term)
      
            // Finally change the term colour
            addAttribute(NSAttributedString.Key.foregroundColor, 
                         value: termsColour, 
                         range: underlineRange)
        }
    }
}

Example:

let someMutableStr = NSMutableAttributedString(string: "Hello World 2017 !")
someMutableStr.changeColourOf(["Hello", "2017"], 
                              toThisColour: .blue, 
                              theStringFontColour: .red)

Edit 2021

 extension NSMutableAttributedString
 {
    func colourTerms(_ terms:[String] = [],
                     withColour colour:UIColor = .blue,
                     onforegroundColour foregroundColour:UIColor = .white)
{
    let fontSize:CGFloat = 25
      self.addAttributes([NSAttributedString.Key.font:UIFont.systemFont(ofSize: fontSize),NSAttributedString.Key.foregroundColor:foregroundColour], range:NSMakeRange(0, self.length) )
    let text = self.string
    for term in terms
    {
        let charCount = term.count
        var options:NSString.EnumerationOptions = .byWords
        switch charCount
        {
            case 1:
                options = .byComposedCharacterSequences
            default:
                if term.contains(" ")
                {
                    options = .bySentences
                }else
                {
                    options = .byWords
                }
        }
        string.enumerateSubstrings(in: text.startIndex..<text.endIndex, 
          options: options)
       { (subString,substringRange,_,_) in
            if subString!.contains(term)
            {
                 self.addAttribute(NSAttributedString.Key.foregroundColor,
              value: colour, 
              range: NSRange(substringRange, in: text))}}}}}

Example 2021

    let attrText = NSMutableAttributedString(string: """
    Hello World 2021!
    Happy 2021 
    """)
    attrText.colourTerms(["Hello","2021"])

    //Before this second color will stay the same , now fixed!
    //See images below

enter image description here Example 2017

Here is the problem Here is the problem enter image description here Now

Upvotes: 2

iii
iii

Reputation: 1614

Make a mutable copy of the attributed string, and then use either:

-setAttributes:range:
-addAttributes:range:
-addAttribute:value:range:
-removeAttributes:range:

for example, to set a red color for the first four letters:

NSMutableAttributedString *mutAttrStr = [attributedString mutableCopy];
CGColorRef redClr = [UIColor redColor].CGColor;
NSDictionary *newAttributes = [NSDictionary dictionaryWithObject:(id)redClr forKey:(id)kCTForegroundColorAttributeName];
[mutAttrStr addAttributes:newAttributes range:NSMakeRange(0, 4)];

http://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/NSMutableAttributedString_Class/Reference/Reference.html

There's no built-in way to draw the background color on iOS. You can create a custom string constant for the attribute, eg "MyBackgroundColorAttributeName", and then you'll have to draw it yourself.

Upvotes: 4

Related Questions