如何在textview中键入“@”后检测字符串

时间:2018-03-21 13:30:26

标签: swift uitextview

我已经做了很长时间了。我阅读了Get currently typed word in UITextViewGet currently typed word in a UITextView的文章,我认为我非常接近。我的问题是,在我能够成功检测到'@'符号之后,由于某种原因,应该返回的单词不会被返回。例如:

    func textViewDidChange(_ textView: UITextView) {
    commentString = commentTextView.text
    commentTextView.setTextTyping(text: commentTextView.text, withHashtagColor: .blue, andMentionColor: .red, andCallBack: callBack, normalFont: UIFont(name: "HelveticaNeue", size: 14)!, hashTagFont: UIFont(name: "HelveticaNeue-Medium", size: 14)!, mentionFont: UIFont(name: "HelveticaNeue-Medium", size: 14)!)
    if let word = textView.currentWord {
        if word.hasPrefix("@")  {
            print(word)
            print(users)
            print("Observing")
        }
    }
}

我能够检测到“@”但是,在.hasPrefix的布尔测试之后,应该遵循的单词不会被打印到控制台。如果我在布尔测试之前打印'word',那么正确的单词将被打印到控制台。这是我用来检测“@”符号的扩展名。

extension UITextView {

    var currentWord : String? {
        let beginning = beginningOfDocument

        if let start = position(from: beginning, offset: selectedRange.location),
            let end = position(from: start, offset: selectedRange.length) {

            let textRange = tokenizer.rangeEnclosingPosition(end, with: .word, inDirection: 1)

            if let textRange = textRange {
                return text(in: textRange)
            }
        }
        return nil
    }
}

提前感谢任何帮助,谢谢!

4 个答案:

答案 0 :(得分:1)

因此,您目前尚未在currentWord中获得全部内容。看起来你只得到@字符。 currentWord是一个变量,看起来你没有正确地迭代textField中的所有字符。我就是这样处理的:

if let splitText = textField.text?.split(separator: " ") {
    for word in splitText {
            if word.hasPrefix("@") {
                print(word) // call whatever function you need here
            } else {
                print("NOPE")
            }
        }
} else {
    print("No Text!!")
}

只有在找到@并且word包含@@之后的每个字符都包含" "(空格)时才会触发

答案 1 :(得分:0)

您可以通过{@ 3}将separating整个textview的文字实现它:

let text = "My Text goes here @ the next text"
let separated = text.components(separatedBy: "@")

从而获得结果数组中的最后一个字符串(separated):

if let textAfterAt = separated.last {
    print(textAfterAt) // " the next text"
}

请注意,如果文本包含多个“@”,结果将是最后一个“@”之后的字符串,例如:

let text = "My Text goes here @ the next text @ the last text after the at"
let separated = text.components(separatedBy: "@")
if let textAfterAt = separated.last {
    print(textAfterAt) // " the last text after the at"
}

答案 2 :(得分:0)

在这种情况下,我的偏好是使用正则表达式,但它似乎比我记得要复杂得多。请参阅下面的代码(游乐场代码)

None
  

<强>输出

     

@two

     

@prepended

#1 我只能使用NSStrings实现这一点,因为最近Swift 4对String的更改(String又是一组字符)。

#2 您现在拥有字符串中每个单词和单词的范围,因此您现在可以进行一些工作/计算并用您想要的任何内容替换每个单词。

答案 3 :(得分:0)

使用委托在键入字符时获取更新。使用正则表达式查找以@开头的所有单词,然后将所需的属性应用于每个匹配项,并将属性字符串分配回文本字段。

    class ViewController: UIViewController {
        let regex = try! NSRegularExpression(pattern: "\\@(\\w+)")
        let highlightAttributes = [NSForegroundColorAttributeName : UIColor.blue]
    }

    extension ViewController: UITextFieldDelegate {
        func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
            guard let originalText = textField.text as? NSString else {
                return false
            }
            let proposedText = originalText.replacingCharacters(in: range, with: string)
            let matches = regex.matches(in: proposedText, options: [], range: NSRange(location: 0, length: proposedText.count))
            let attributedText = NSMutableAttributedString(string: proposedText)
            matches.forEach {attributedText.addAttributes(self.highlightAttributes, range: $0.range)}
            textField.attributedText = attributedText
            return false
        }
    }