【问题标题】:Get color changed words of attributed string获取属性字符串的颜色更改词
【发布时间】:2017-06-18 19:13:54
【问题描述】:

我有一个UITextView,它允许通过点击它来选择文本中的单词。如果点击它,则通过更改NSForegroundColor 属性以颜色突出显示该单词。 再次点击它会通过将颜色更改回文本颜色来取消选择它。

现在我需要知道UITextView 中所有选定的单词。

第一个想法是删除所有特殊字符并在空格处拆分文本。然后检查颜色属性是否等于每个单独单词的选定/突出显示颜色。 但是属性字符串不允许在字符处拆分或删除组件。 NSAttributedString 也没有。

第二个想法是将突出显示部分的范围保存在一个数组中并对其进行迭代以获得突出显示的部分。但这对我来说似乎有点太复杂了,特别是当我需要正确的单词顺序时,数组不能保证,每次点击时添加/删除 (例如,假设文本是:“这是一个测试”

Tap this -> index 0
Tap test -> index 1
Tap this -> test becomes index 0
Tap this -> this becomes index 1

那么订单就不好了。

我已经想出了如何获取属性字符串的颜色。那不是问题。

我如何遍历属性字符串并找出改变颜色的单词或解决此问题的最佳方法是什么?

谢谢!

问候

【问题讨论】:

    标签: ios swift colors uitextview highlight


    【解决方案1】:

    您可以遍历属性字符串以查找颜色属性。

    以下代码演示如何:

    // This generates a test attributed string.
    // You actually want the attributedText property of your text view
    let str = NSMutableAttributedString(string: "This is a test of the following code")
    str.addAttributes([NSForegroundColorAttributeName:UIColor.red], range: NSMakeRange(0, 4))
    str.addAttributes([NSForegroundColorAttributeName:UIColor.red], range: NSMakeRange(8, 1))
    str.addAttributes([NSForegroundColorAttributeName:UIColor.red], range: NSMakeRange(15, 2))
    print(str)
    

    以上打印:

    This{
        NSColor = "UIExtendedSRGBColorSpace 1 0 0 1";
    } is {
    }a{
        NSColor = "UIExtendedSRGBColorSpace 1 0 0 1";
    } test {
    }of{
        NSColor = "UIExtendedSRGBColorSpace 1 0 0 1";
    } the following code{
    }
    

    此代码处理属性字符串。任何用前景色格式化的文本范围都将被放入 words 数组中。

    var words = [String]()
    str.enumerateAttribute(NSForegroundColorAttributeName, in: NSMakeRange(0, str.length), options: []) { (value, range, stop) in
        if value != nil {
            let word = str.attributedSubstring(from: range).string
            words.append(word)
        }
    }
    print(words)
    

    打印出来:

    [“这个”、“一个”、“的”]

    【讨论】:

      【解决方案2】:

      我可以建议你为选定的范围创建某种存储,然后基于这个范围你可以自定义这个词的外观,而不是其他方式。它将允许您每次访问选定的单词而无需检查整个文本的属性。

      【讨论】:

      • 感谢您的建议。据我了解您为什么建议这样做,我坚持使用另一种方法,因为我的项目对整个字符串进行一次迭代并不重要。
      【解决方案3】:

      虽然我同意 Piotr 你应该存储 Ranges 来回答你的问题:

      attributedString.enumerateAttributes(in: NSMakeRange(0, attributedString.length), options: []) { attributes, range, _ in
          if let color = attributes[NSForegroundColorAttributeName] as? UIColor,
              color == YOUR_HIGHLIGHT_COLOR {
              let nString = attributedString.string as NSString
              let word = nString.substring(with: range)
              // Do what you want with the word
          }
      }
      

      【讨论】:

        猜你喜欢
        • 2020-09-22
        • 1970-01-01
        • 1970-01-01
        • 2015-10-19
        • 1970-01-01
        • 2012-04-13
        • 2014-10-24
        • 2013-03-30
        相关资源
        最近更新 更多