2

In a NSAttributed type statement, I want to keep the existing attributed value and give it a new attributed value.

The problem is that replacingOccurrences is only possible for string types, as I want to give a new value every time the word appears in the entire sentence.

If I change NSAttributedString to string type, the attributed value is deleted. I must keep the existing values.

How can I do that?

zx485
  • 28,498
  • 28
  • 50
  • 59

2 Answers2

0

You can use replaceCharacters. You can find the range of the substring you want to remove and use it as your range.

Ben A.
  • 874
  • 7
  • 23
  • @allanWay You can iterate through it, using the range of the next substring for each, replacing it with an attributed string. – Ben A. Mar 19 '18 at 04:40
  • As you said, if duplicate text exists, you can not get the desired effect. –  Mar 19 '18 at 04:49
0

To get this working,

1. First you need to find the indices of all the duplicate substrings existing in a string. To get that you can use this: https://stackoverflow.com/a/40413665/5716829

extension String {
    func indicesOf(string: String) -> [Int] {
        var indices = [Int]()
        var searchStartIndex = self.startIndex

        while searchStartIndex < self.endIndex,
            let range = self.range(of: string, range: searchStartIndex..<self.endIndex),
            !range.isEmpty
        {
            let index = distance(from: self.startIndex, to: range.lowerBound)
            indices.append(index)
            searchStartIndex = range.upperBound
        }

        return indices
    }
}

2. Next you need to apply your desired attribute to substring at each index, i.e.

    let str = "The problem is that replacingOccurrences Hello is only possible for string types, as I want to give Hello a new value every time Hello the word appears in the entire sentence Hello."
    let indices = str.indicesOf(string: "Hello")
    let attrStr = NSMutableAttributedString(string: str, attributes: [.foregroundColor : UIColor.blue])
    for index in indices
    {
        //You can write your own logic to specify the color for each duplicate. I have used some hardcode indices
        var color: UIColor
        switch index
        {
        case 41:
            color = .orange
        case 100:
            color = .magenta
        case 129:
            color = .green
        default:
            color = .red
        }
        attrStr.addAttribute(.foregroundColor, value: color, range: NSRange(location: index, length: "Hello".count))
    }

Screenshot:

enter image description here

Let me know if you still face any issues. Happy Coding..

PGDev
  • 23,751
  • 6
  • 34
  • 88
  • 41, 100 and 129 are the indices of "Hello" that I got in indices array. That's why I said I have just hardcoded them to get it working. You can add your own logic for adding colors to different indices. – PGDev Mar 19 '18 at 06:55