Search code examples
iosswiftuitextviewnsmutablestringnsmutableattributedstring

why does my font in UITextView changes style without a reason in swift?


I have a UITextView in my swift app and I'm setting up the font in viewDidLoad:

let font = UIFont(name: "AppleSDGothicNeo-Light", size: 16.0)

myTextView.font = font

It works ok, when I run the app and writes something in the text view, I see:

enter image description here

Now, I have a method that checks given text and finds and highlights hashtags in it. The method is as follows:

func formatTextInTextView(textView: UITextView) {
    textView.scrollEnabled = false
    let selectedRange = textView.selectedRange
    let text = textView.text

    // This will give me an attributedString with the base text-style
    let attributedString = NSMutableAttributedString(string: text)

    let regex = try? NSRegularExpression(pattern: "#(\\w+)", options: [])
    let matches = regex!.matchesInString(text, options: [], range: NSMakeRange(0, text.characters.count))

    for match in matches {
        let matchRange = match.rangeAtIndex(0)

        let titleDict: NSDictionary = [NSForegroundColorAttributeName: UIColor(red: 244/255, green: 137/255, blue: 0/255, alpha: 1.0), NSFontAttributeName: font!]

        attributedString.addAttributes(titleDict as! [String : AnyObject], range: matchRange)
    }

    textView.attributedText = attributedString
    textView.selectedRange = selectedRange
    textView.scrollEnabled = true
} 

I added this method to the:

func textViewDidChange(textView: UITextView) {
    formatTextInTextView(textView)
}

and now with every user's input I'm dynamically checking if it's a hashtag or not, and if it is - highlights the text to orange. At least it should be in theory. So this happens when the method is enabled:

As soon as I start writing text:

enter image description here

(this seems like a system font to me)

and when I add hashtag:

enter image description here

it works for the hashtag, but the rest of the text gets - seems like - default style. What's the problem here? :|


Solution

  • You need to specify your desired font when you initially create the attributed string, not just for the parts with a different color.

    func formatTextInTextView(textView: UITextView) {
        textView.scrollEnabled = false
        let selectedRange = textView.selectedRange
        let text = textView.text
    
        let titleDict: NSDictionary = [NSFontAttributeName: font!]
    
        // This will give me an attributedString with the desired font
        let attributedString = NSMutableAttributedString(string: text, attributes: titleDict)
    
        let regex = try? NSRegularExpression(pattern: "#(\\w+)", options: [])
        let matches = regex!.matchesInString(text, options: [], range: NSMakeRange(0, text.characters.count))
    
        for match in matches {
            let matchRange = match.rangeAtIndex(0)
    
            let titleDict: NSDictionary = [NSForegroundColorAttributeName: UIColor(red: 244/255, green: 137/255, blue: 0/255, alpha: 1.0)]
    
            attributedString.addAttributes(titleDict as! [String : AnyObject], range: matchRange)
        }
    
        textView.attributedText = attributedString
        textView.selectedRange = selectedRange
        textView.scrollEnabled = true
    }