user3766930
user3766930

Reputation: 5839

I'm implementing hashtag recognizer in UITextView but it never highlights two words with the same begining

I found this question: How to make UITextView detect hashtags? and I copied the accepted answer into my code. I also set up a delegate to my textview and then put this code:

func textViewDidChange(textView: UITextView) { 
    textView.resolveHashTags()
}

By doing that I want to check the user's input on the textview and each time user types a #hashtag - I will automatically highlight it.

But there is a weird problem: it never highlights words that starts with the same letters.

It looks like this:

enter image description here

what might be the problem here?

Upvotes: 2

Views: 2333

Answers (3)

Vladislav Kovalyov
Vladislav Kovalyov

Reputation: 803

Here is Swift 5 solution as String extension:

extension String
{
    func withHashTags(color: UIColor) -> NSMutableAttributedString
    {
        let words = self.components(separatedBy: " ")
        
        let attributedString = NSMutableAttributedString(string: self)
        
        for word in words
        {
            if word.hasPrefix("#")
            {
                let range = (self as NSString).range(of: word)
                attributedString.addAttribute(.foregroundColor, value: color, range: range)
            }
        }
        
        return attributedString
    }
}

Pass param color to set specific color for hashtags

Upvotes: 1

Shree Ranga Raju
Shree Ranga Raju

Reputation: 691

Little late to the party

    private func getHashTags(from caption: String) -> [String] {
    var words: [String] = []
    let texts = caption.components(separatedBy: " ")
    for text in texts.filter({ $0.hasPrefix("#") }) {
        if text.count > 1 {
            let subString = String(text.suffix(text.count - 1))
            words.append(subString)
        }
    }
    return words
}

Upvotes: 0

unniverzal
unniverzal

Reputation: 803

func resolveHashTags(text : String) -> NSAttributedString{
    var length : Int = 0
    let text:String = text
    let words:[String] = text.separate(withChar: " ")
    let hashtagWords = words.flatMap({$0.separate(withChar: "#")})
    let attrs = [NSFontAttributeName : UIFont.systemFont(ofSize: 17.0)]
    let attrString = NSMutableAttributedString(string: text, attributes:attrs)
    for word in hashtagWords {
        if word.hasPrefix("#") {
                let matchRange:NSRange = NSMakeRange(length, word.characters.count)
                let stringifiedWord:String = word

                attrString.addAttribute(NSLinkAttributeName, value: "hash:\(stringifiedWord)", range: matchRange)
        }
        length += word.characters.count
    }
    return attrString
}

To separate words I used a string Extension

extension String {
    public func separate(withChar char : String) -> [String]{
    var word : String = ""
    var words : [String] = [String]()
    for chararacter in self.characters {
        if String(chararacter) == char && word != "" {
            words.append(word)
            word = char
        }else {
            word += String(chararacter)
        }
    }
    words.append(word)
    return words
}

}

I hope this is what you are looking for. Tell me if it worked out for you.

Edit :

   func textViewDidChange(_ textView: UITextView) {
        textView.attributedText = resolveHashTags(text: textView.text)
        textView.linkTextAttributes = [NSForegroundColorAttributeName : UIColor.red]
    }

Edit 2: Updated for swift 3.

Upvotes: 2

Related Questions