11

I am extracting from a DB contents as strings. With a method I extract the longest word out of this string.

Now I would like to print out the entire string to a text label but would like to highlight the longest word in a different color and text style within the string.

How can I do that? Do I need to cut the string into pieces - set the formatting - and put them all together again before giving it to the label?

Or is there any other (better) way?

user1555112
  • 1,897
  • 6
  • 24
  • 43
  • Possible duplicate of [Example of NSAttributedString with two different font sizes?](http://stackoverflow.com/questions/18365631/example-of-nsattributedstring-with-two-different-font-sizes) – SwiftArchitect Feb 02 '16 at 15:13

3 Answers3

33

If you already know the longest word you have to get the range of that word in the string. I prefer the NSString method rangeOfString: for this.

You then create a NSMutableAttributedString from the string, with your default attributes. Finally you apply highlighting attributes to the range you figured out earlier.

let longString = "Lorem ipsum dolor. VeryLongWord ipsum foobar"
let longestWord = "VeryLongWord"

let longestWordRange = (longString as NSString).rangeOfString(longestWord)

let attributedString = NSMutableAttributedString(string: longString, attributes: [NSFontAttributeName : UIFont.systemFontOfSize(20)])

attributedString.setAttributes([NSFontAttributeName : UIFont.boldSystemFontOfSize(20), NSForegroundColorAttributeName : UIColor.redColor()], range: longestWordRange)


label.attributedText = attributedString

Update for Swift 5.0

let longestWordRange = (longString as NSString).range(of: longestWord)

let attributedString = NSMutableAttributedString(string: longString, attributes: [NSAttributedStringKey.font : UIFont.systemFont(ofSize: 20)])

attributedString.setAttributes([NSAttributedStringKey.font : UIFont.boldSystemFont(ofSize: 20), NSAttributedStringKey.foregroundColor : UIColor.red], range: longestWordRange)

Which looks like this in my playground:

enter image description here

Ashutosh Shukla
  • 358
  • 5
  • 14
Matthias Bauch
  • 89,811
  • 20
  • 225
  • 247
  • this will not gonna work if you have repeated characters in string. Imagine you have next string: "VeryLongWord Lorem ipsum dolor. VeryLongWord ipsum foobar" And you need to change font only for VeryLongWord which is befor ipsum word. This code fails this. – swift2geek Jan 17 '20 at 17:33
3

You want to look at Attributed Strings and NSRange. You can use both of these together to create different styles for ranges in the string. Here is a snippet:

myMutableString = NSMutableAttributedString(string: myString, attributes: [NSFontAttributeName:UIFont(name: "Georgia", size: 18.0)!])

//Add more attributes here:
myMutableString.addAttribute(NSFontAttributeName, value: UIFont(name: "Chalkduster", size: 24.0), range: NSRange(location: 7,length: 5))
myMutableString.addAttribute(NSFontAttributeName, value: UIFont(name: "AmericanTypewriter-Bold", size: 18.0)!, range: NSRange(location:2,length:4))
myMutableString.addAttribute(NSForegroundColorAttributeName, value: UIColor.redColor(), range: NSRange(location:2,length:4))

myMutableString.addAttribute(NSFontAttributeName, value: UIFont(name: "Georgia", size: 36.0)!, range: NSRange(location: 0, length: 1))
myMutableString.addAttribute(NSStrokeColorAttributeName, value: UIColor.blueColor(), range:  NSRange(location: 0, length: 1))
myMutableString.addAttribute(NSStrokeWidthAttributeName, value: 2, range: NSRange(location: 0, length: 1))

myMutableString.addAttribute(NSBackgroundColorAttributeName, value: UIColor.greenColor(), range: NSRange(location: 0, length: myString.length))
myLabel.backgroundColor = UIColor.grayColor()

//Apply to the label
myLabel.attributedText = myMutableString
Chackle
  • 2,249
  • 18
  • 34
  • I'm pretty sure you can create an `NSDictionary` of the attributes and add them all at once. A lot cleaner than adding them one-by-one :) – Lord Zsolt Mar 20 '15 at 11:39
  • Totally agree, I think this step is more preferable however for someone new to NSAttributedString however. Easier to read line by line :). I may consider adding the dictionary version however. Thanks – Chackle Mar 20 '15 at 11:41
  • @Chackle That sounds good! I will have a look to it! I just need to figure out how to set the location and length... But that's a good start! – user1555112 Mar 20 '15 at 11:42
1

NSMutableAttributedString.

You create an NSMutableAttributedString and apply the effects you'd like with addAttributes:range.

Then assign it to the attributedText property of your UILabel.

Lord Zsolt
  • 6,492
  • 9
  • 46
  • 76