我正在 UITextView 中实现标签识别器,但它从不突出显示具有相同开头的两个单词

Posted

技术标签:

【中文标题】我正在 UITextView 中实现标签识别器,但它从不突出显示具有相同开头的两个单词【英文标题】:I'm implementing hashtag recognizer in UITextView but it never highlights two words with the same begining 【发布时间】:2016-09-18 09:06:27 【问题描述】:

我发现了这个问题:How to make UITextView detect hashtags? 并将接受的答案复制到我的代码中。我还为我的 textview 设置了一个delegate,然后输入以下代码:

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

通过这样做,我想检查用户在 textview 上的输入,并且每次用户键入 #hashtag 时,我都会自动突出显示它。

但有一个奇怪的问题:它永远不会突出显示以相同字母开头的单词。

看起来像这样:

这可能是什么问题?

【问题讨论】:

你可能想看看github.com/optonaut/ActiveLabel.swift我在最近的一个项目中使用了它,它运行得非常好。 @Sarcoma 谢谢,但它不适用于输入文本视图,所以这就是我不使用它的原因...... 我知道你现在想做什么,实际上我上周写了一个脚本来做这件事,但提到了@name。不过我身上没有。 我使用了类似的方法:***.com/questions/31129527/… 检查@符号的字符范围,保持该位置直到空格或光标移动,并检查那里和光标之间的所有字符。如果到我回到工作岗位时没有人回答这个问题,我会发布我的解决方案。 @Sarcoma 谢谢伙计,我将不胜感激! 【参考方案1】:
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

为了分隔单词我使用了一个字符串扩展

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



我希望这是您正在寻找的。告诉我它是否适合你。

编辑:

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

编辑 2: 为 swift 3 更新。

【讨论】:

谢谢你,抱歉回复晚了...你能告诉我如何使用它在 textview 中实时突出显示单词吗? 如果 textview 在#tag 之前包含表情符号怎么办?【参考方案2】:

晚会有点晚了

    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

【讨论】:

【参考方案3】:

这是 Swift 5 解决方案作为String 扩展:

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
    

传递参数color 为主题标签设置特定颜色

【讨论】:

以上是关于我正在 UITextView 中实现标签识别器,但它从不突出显示具有相同开头的两个单词的主要内容,如果未能解决你的问题,请参考以下文章

UITextView自动调整大小以调整单行iOS Objective -C

如果在其他类中实现,自定义点击识别器方法将不起作用

swift 在UITextView(Swift)中实现占位符的正确方法

UITextView 的 UIGestureRecognizer 防止键盘在点击时出现

在 OpenCV 中实现热视觉 [关闭]

在 UITableView 中实现动态增长的 TextView