【问题标题】:Keeping track of and changing color of text in UITextView跟踪和更改 UITextView 中文本的颜色
【发布时间】:2019-01-13 20:05:57
【问题描述】:

由于用户在文本视图中键入,我正在查看每个单词并查看它与我拥有的数组中的单词匹配。如果匹配,则将单词更改为蓝色,并将布尔变量 didFindACertainWord 设置为 true(以确保只有一个单词是蓝色的)。我能够成功完成这部分,但出现了一些错误:

  1. 我更改为蓝色的某个单词有效,但在字体之前键入的单词已更改,并且我在该单词之后键入的任何内容也是蓝色的(我不想要)。 我只想把某个单词改成蓝色,其他单词保持黑色,字体和以前一样。

  2. 我不知道如何确定用户是否删除了某个单词。如果他们这样做,我想将某个单词的颜色改回黑色(在他们删除某个单词的第一个字符之后)并将 didFindACertainWord 设置为 false。

这是我在 textViewDidChange 方法中的当前代码:

func textViewDidChange(_ textView: UITextView) {
    //get last word typed
    let size = textView.text.reversed().firstIndex(of: " ") ?? textView.text.count
    let startWord = textView.text.index(textView.text.endIndex, offsetBy: -size)
    let lastWord = textView.text[startWord...]

    //check if last word is in array and we did not already find one
    if certainWords.contains(String(lastWord)) && !didFindACertainWord {
        didFindACertainWord = true

        //change color of the word
        let attributedString = NSMutableAttributedString.init(string: textView.text)
        let range = (textView.text as NSString).range(of: String(lastWord))
        attributedString.addAttributes([NSAttributedString.Key.foregroundColor: UIColor.blue, NSAttributedString.Key.font: UIFont(name: "Avenir-Roman", size: 18)], range: range)
        textView.attributedText = attributedString
    }
}

我错过了什么/我怎样才能成功地做到这一点?附言textview中所有文本的字体应为UIFont(name: "Avenir-Roman", size: 18)

我正在搜索每个单词,因为在用户键入动作词后,如果它们与动作词相关,我需要阅读下一个单词以将它们加粗。例如,如果用户输入“see Paris London Berlin to find the best food”,则动作词是“see”,加粗的相关词是地方“Paris Italy France”和不相关的词(将在常规字体)是“寻找最好的”

【问题讨论】:

  • 对于第一个问题,这是因为您应该做一个“else”案例,并重置颜色和布尔值。对于第二个,您不需要只处理最后一个单词,而是检查整个字符串中是否有匹配项。

标签: ios swift string uitextview


【解决方案1】:

对于第一个问题,这是因为您应该做一个“else”案例,并重置颜色和布尔值。 您应该添加:

} else {
    didFindACertainWord = false
    textView.attributedText = attributedString
}

对于第二个,您不需要只处理最后一个单词,而是检查整个字符串中是否有匹配项。

未测试,但应该可以工作:

func textViewDidChange(_ textView: UITextView) {

    let attributedString = NSMutableAttributedString(string: textView.text,
                                                     attributes: [.font: UIFont(name: "Avenir-Roman", size: 18)])

    let allWords = attributedString.string.components(separatedBy: CharacterSet.whitespaces)
    if let firstMatch = allWords.first(where: { return certainWords.contains($0)}) {
        didFindACertainWord = true
        let firstMatchRange = (attributedString.string as NSString).range(of: firstMatch)
        attributedString.addAttribute(.foregroundColor, value: UIColor.blue, range: firstMatchRange)
    } else {
        didFindACertainWord = false
    }
    textView.attributedText = attributedString
}

【讨论】:

  • 如果给我错误,您的答案中的if let firstMatch = allWords.first(where: containsWords($0)) { 行。错误指向containsWords,因为它没有被识别。当我第一次遇到此错误时,我假设您正在尝试引用我正在查找的单词数组,因此我将其更改为 certainWords。一旦我这样做了,现在的错误是:“匿名闭包参数不包含在闭包中”。我不确定这意味着什么或如何解决它。
  • ...where: certainWords(contains: $0)... 代替?
  • 太棒了!有效。您是否偶然知道在用户输入操作词后检查这些词是否相关(在我帖子的最后一段)的聪明方法
  • 一旦你找到了这个词,你可以使用range(of:options:range:)(如果你仍然想使用NSString而不是String)来搜索任何东西,但是在动作词之后(或之前) ,range 参数允许您这样做。
猜你喜欢
  • 2016-02-02
  • 1970-01-01
  • 2012-07-11
  • 1970-01-01
  • 1970-01-01
  • 2019-10-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多