Search code examples
swiftstringfontsuilabelbold

Swift make UILabel text bold in between custom identifier


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?


Solution

  • 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.