-1

I have a UILabel with a text of

This is not bold, -bold- this is bold, -/bold- and this is another not bold, -bold- this is another bold -/bold-.

now, I want to change the font of the text in between every -bold- and -/bold- in text to bold so it will become something like this

This is not bold, this is bold, and this is another not bold, this is another bold.

How can I do that?

Dylan
  • 1,121
  • 1
  • 13
  • 28

4 Answers4

1

You can use a NSMutableAttributedString and set it to UILabel's attributedText property.

let label = UILabel()
//Choose your bold font
let boldAttributes = [NSFontAttributeName : UIFont.boldSystemFont(ofSize: 15)]
let mutableAttributedString = NSMutableAttributedString()
mutableAttributedString.append(NSAttributedString(string: "Non-bold text #1", attributes: nil))
mutableAttributedString.append(NSAttributedString(string: "Bold text #1", attributes: boldAttributes))
mutableAttributedString.append(NSAttributedString(string: "Non-bold text #2", attributes: nil))
mutableAttributedString.append(NSAttributedString(string: "Bold text #2", attributes: boldAttributes))
label.attributedText = mutableAttributedString
Kunal Shah
  • 1,071
  • 9
  • 24
  • but that given string was changing time to time, it can be `some random -bold- string -/bold- and another -bold- randomised string -/bold-` so i can't put static strings in the function. – Dylan Mar 31 '20 at 05:19
0

First, get the strings within the delimiter.

let query = "This is not bold, -bold- this is bold, -/bold- and this is another not bold, -bold- this is another bold -/bold-"
let regex = try! NSRegularExpression(pattern: "-bold- (.*?) -/bold-", options: [])
var results = [String]()
regex.enumerateMatches(in: query, options: [], range: NSMakeRange(0, query.utf16.count)) { result, flags, stop in

    if let r = result?.range(at: 1),
        let range = Range(r, in: query) {
        results.append(String(query[range]))
    }
}

print(results)

Next, Create a string extension method like below.

extension String {

    func attributedString(with style: [NSAttributedString.Key: Any]? = nil,
                          and highlightedTextArray: [String],
                          with highlightedTextStyleArray: [[NSAttributedString.Key: Any]?]) -> NSAttributedString {

        let formattedString = NSMutableAttributedString(string: self, attributes: style)
        if highlightedTextArray.count != highlightedTextStyleArray.count {
            return formattedString
        }

        for (highlightedText, highlightedTextStyle) in zip(highlightedTextArray, highlightedTextStyleArray) {
            let highlightedTextRange: NSRange = (self as NSString).range(of: highlightedText as String)
            formattedString.setAttributes(highlightedTextStyle, range: highlightedTextRange)
        }

        return formattedString
    }
}

Method details:

  • first argument: Font style and other attributes to be applied for complete string.
  • second argument: Array of strings for which new style to be applied.
  • third argument: New Style (in this case, Bold) to be applied.
  • returns resultant attributed string.

Finally, call the method as below.

let attributedText = query.attributedString(with: [.font: UIFont.systemFont(ofSize: 12.0, weight: .regular)],
                       and: results,
                       with: [[.font: UIFont.systemFont(ofSize: 12.0, weight: .bold)]])

Hope it helps.

Anand
  • 1,820
  • 2
  • 18
  • 25
  • your last parameter on query.attributedString is not an array and it gives me an error saying `Contextual type '[[NSAttributedString.Key : Any]?]' cannot be used with dictionary literal` so I changed it to `with: [[.font: UIFont.systemFont(ofSize: 12.0, weight: .bold)]]` after I do that I write `label.attributedText = attributedText` and the text on label was still the value of the `query` variable. – Dylan Mar 31 '20 at 06:17
  • I corrected the last argument. Please check whether results array contains the list of strings that should be made bold. – Anand Mar 31 '20 at 07:34
0

Implementation :

Write an extension for NSMutableAttributedString and implement methods for bold and normal string arributes.

 extension NSMutableAttributedString {


    func bold(_ value:String) -> NSMutableAttributedString {

        let attributes:[NSAttributedString.Key : Any] = [.font : UIFont.boldSystemFont(ofSize: 15)]

        self.append(NSAttributedString(string: value, attributes:attributes))
        return self
    }

    func normal(_ value:String) -> NSMutableAttributedString {

        let attributes:[NSAttributedString.Key : Any] = [.font : UIFont.systemFont(ofSize: 15)]

        self.append(NSAttributedString(string: value, attributes:attributes))
        return self
    }
}

Usage:

textLabel.attributedText = NSMutableAttributedString().normal("This is not bold, ").bold("this is bold, ").normal("and this is another not bold, ").bold("this is another bold.")

Result: enter image description here

Catherine
  • 199
  • 6
0

Working for me

titleLabel.font = UIFont.boldSystemFont(ofSize: 11)
PK Chahar
  • 81
  • 2
  • 10