Search code examples
swiftoptimizationdispatch

Grand Center Dispatch For Loop


for i in 0...attString.length-1
{
    attString.enumerateAttribute(NSBackgroundColorAttributeName, in: NSMakeRange(i,1), options: NSAttributedString.EnumerationOptions(rawValue: 0)) { (value, range, stop) -> Void in
        if let exValue = value as? UIColor
        {
            if self.compareColors(c1: exValue, c2: (UIColor(hex: 0x2e4270))) ||
               self.compareColors(c1: exValue, c2: (UIColor(hex: 0xc0e1ff))) ||
               self.compareColors(c1: exValue, c2: (UIColor(hex: 0x7a99b8))) ||
               self.compareColors(c1: exValue, c2: (UIColor(hex: 0xaad5fb)))
            {
                aRange = NSMakeRange(i, 1)
                myValue = self.styles.blueHighlightColor()
                 //DispatchQueue.main.async {
                mutableAttString.addAttribute(attributeName, value: myValue, range: aRange)
                //}
                self.saveChanges = true
            }
            else if self.compareColors(c1: exValue, c2: (UIColor(hex: 0x385324))) ||
                self.compareColors(c1: exValue, c2: (UIColor(hex: 0xbde970))) ||
                self.compareColors(c1: exValue, c2: (UIColor(hex: 0x88a752)))
            {
                aRange = NSMakeRange(i, 1)
                myValue = self.styles.greenHighlightColor()
                 //DispatchQueue.main.async {
                mutableAttString.addAttribute(attributeName, value: myValue, range: aRange)
               // }
                self.saveChanges = true
            }
            else if self.compareColors(c1: exValue, c2: (UIColor(hex: 0x624b85))) ||
            self.compareColors(c1: exValue, c2: (UIColor(hex: 0xd6affb))) ||
            self.compareColors(c1: exValue, c2: (UIColor(hex: 0x997eb8))) ||
            self.compareColors(c1: exValue, c2: (UIColor(hex: 0xd6affb)))
            {
                aRange = NSMakeRange(i, 1)
                myValue = self.styles.pinkHighlightColor()
                // DispatchQueue.main.async {
                mutableAttString.addAttribute(attributeName, value: myValue, range: aRange)
                //}
                self.saveChanges = true
            }
            else if self.compareColors(c1: exValue, c2: (UIColor(hex: 0x7b5b15))) ||
                self.compareColors(c1: exValue, c2: (UIColor(hex: 0xfbe769))) ||
                self.compareColors(c1: exValue, c2: (UIColor(hex: 0xb4a64d)))
            {
                aRange = NSMakeRange(i, 1)

                myValue = self.styles.yellowHighlightColor()
                // DispatchQueue.main.async {
                mutableAttString.addAttribute(attributeName, value: myValue, range: aRange)
                //}
                self.saveChanges = true
            }
        }
    }
} // For loop end

I iterate through every NSAttributed char and I'm checking its background color. If it is clear ok, or any other color not defined in the if statements. It works fine, but it's kinda slow when I enter larger text. I tried using DispatchQueue.concurrentPerform(iterations:execute:), but it crashes, I don't why.


Solution

  • There's no reason for the outer for loop. Just enumerate the attributed string looking for NSBackgroundColorAttributeName. Simply replace whatever range you are given with the new color.

    attString.enumerateAttribute(NSBackgroundColorAttributeName, in: NSMakeRange(0, attString.length), options: NSAttributedString.EnumerationOptions(rawValue: 0)) { (value, range, stop) -> Void in
        if let exValue = value as? UIColor
        {
            if self.compareColors(c1: exValue, c2: (UIColor(hex: 0x2e4270))) ||
               self.compareColors(c1: exValue, c2: (UIColor(hex: 0xc0e1ff))) ||
               self.compareColors(c1: exValue, c2: (UIColor(hex: 0x7a99b8))) ||
               self.compareColors(c1: exValue, c2: (UIColor(hex: 0xaad5fb)))
            {
                myValue = self.styles.blueHighlightColor()
                 //DispatchQueue.main.async {
                mutableAttString.addAttribute(attributeName, value: myValue, range: range)
                //}
                self.saveChanges = true
            }
            else if self.compareColors(c1: exValue, c2: (UIColor(hex: 0x385324))) ||
                self.compareColors(c1: exValue, c2: (UIColor(hex: 0xbde970))) ||
                self.compareColors(c1: exValue, c2: (UIColor(hex: 0x88a752)))
            {
                myValue = self.styles.greenHighlightColor()
                 //DispatchQueue.main.async {
                mutableAttString.addAttribute(attributeName, value: myValue, range: range)
               // }
                self.saveChanges = true
            }
            else if self.compareColors(c1: exValue, c2: (UIColor(hex: 0x624b85))) ||
            self.compareColors(c1: exValue, c2: (UIColor(hex: 0xd6affb))) ||
            self.compareColors(c1: exValue, c2: (UIColor(hex: 0x997eb8))) ||
            self.compareColors(c1: exValue, c2: (UIColor(hex: 0xd6affb)))
            {
                myValue = self.styles.pinkHighlightColor()
                // DispatchQueue.main.async {
                mutableAttString.addAttribute(attributeName, value: myValue, range: range)
                //}
                self.saveChanges = true
            }
            else if self.compareColors(c1: exValue, c2: (UIColor(hex: 0x7b5b15))) ||
                self.compareColors(c1: exValue, c2: (UIColor(hex: 0xfbe769))) ||
                self.compareColors(c1: exValue, c2: (UIColor(hex: 0xb4a64d)))
            {
                myValue = self.styles.yellowHighlightColor()
                // DispatchQueue.main.async {
                mutableAttString.addAttribute(attributeName, value: myValue, range: range)
                //}
                self.saveChanges = true
            }
        }
    }
    

    Once that is done you can improve this even further. Create a dictionary of color mappings. If exValue is found as a key, use its value as the replacement color.