Makaille
Makaille

Reputation: 1666

Multiple range on NSMutableAttributedString

i'm trying to set bold font two different string range in a string. I know how to do it range by range but is it possible to do it one time with multiple range. I don't like to repeat code.

Here's my code

if let rankString = trophy.fullRank.value {
    var secondRankString = "some string"
    var string = SRUtils.LocalizedString("unlocked.description", comment: "")
    string = String(format: string, trophy.trophiesNumber.value!, rankString)

    let atStr = NSMutableAttributedString(string: string)
    //Here i need to add rankString and other range
    let textRange = (string as NSString).range(of: rankString)

    if let font = UIFont(name: "HelveticaNeue-Bold", size: 16) {
        atStr.addAttribute(NSFontAttributeName, value: font, range: textRange)
        self.trophyDescription.value = atStr
    }
}

If for example:

var string = "Hello do you need a cat" 
var rankString = "cat" 

Result with my code: "Hello do you need a cat"

What i need it's :

var mytring = "Hello do you need a cat"
var rankString = "cat"
var secondRankString = "need"

Excepted result : "Hello do you need a cat"

So how i can, in swift 3, add multiple range to apply, without multiple declaration of variable... is it possible ?

Upvotes: 0

Views: 2955

Answers (1)

vikingosegundo
vikingosegundo

Reputation: 52237

two or more, use a for — Edsger W. Dijkstra

This code

import UIKit

let string = "Hello do you need a cat"
let attributedString = NSMutableAttributedString(string: string)
if let font = UIFont(name: "HelveticaNeue", size: 16) {
    attributedString.addAttribute(NSFontAttributeName, value: font, range: NSRange(location:0, length: string.characters.count))
}

let highlightedWords = ["cat", "need"]

for highlightedWord in highlightedWords {
    let textRange = (string as NSString).range(of: highlightedWord)

    if let font = UIFont(name: "HelveticaNeue-Bold", size: 16) {
        attributedString.addAttribute(NSFontAttributeName, value: font, range: textRange)
    }
}

let label = UILabel(frame: CGRect(x: 0, y: 0, width: 100, height: 100))
label.attributedText = attributedString
label.sizeToFit()

results in

screenshot


i was just searching an other way to do it without for or multiple declaration

A for loop can always be expressed as a more generell while loop. But I find for loops easier to understand.

var highlightedWords = ["cat", "need"]

repeat {

    if let highlightedWord = highlightedWords.popLast() {
        let textRange = (string as NSString).range(of: highlightedWord)

        if let font = UIFont(name: "HelveticaNeue-Bold", size: 16) {
            attributedString.addAttribute(NSFontAttributeName, value: font, range: textRange)
        }
    }

} while highlightedWords.count > 0

Upvotes: 13

Related Questions