2

I have a table view that every time I create a new row, a different color is randomly created to change it`s background. using this function:

func getRandomColor() -> UIColor{
    let red:CGFloat = CGFloat(drand48())
    let green:CGFloat = CGFloat(drand48())
    let blue:CGFloat = CGFloat(drand48())

    return UIColor(red:red, green: green, blue: blue, alpha: 1.0)
} 

I store the color in an array, doing this I want to avoid equals colors in my table view. The array is populated when the table view is created in table view cellForRow, like this:

colors.append(category.color as! UIColor)

category is my object.

The problem is when I close the app and starts it again. The memory continuos and start to randomly create the same colors. So I'm trying to compare colors to keep generating colors until it is a new color. Using this function:

 func validateColor(color: UIColor) -> Bool {

    let primeiraCor = colors.first! as UIColor

    if primeiraCor == color {
        return false
    } else {
        return true
    }
} 

colors is my array of color, and color the color I want to compare. But every time the function is called it's return true.

What can I do?

Eduardo Bonfa
  • 290
  • 1
  • 4
  • 15
  • You're always comparing with the first element of your colour array - you'll need to iterate over all colours to see if you have a duplicated. – Steve Ives Feb 20 '17 at 11:11
  • So u have an [Colors] with 10 UIColor elements and when u create a random color, u need to check if the randomly generated colors array has same elements as the original colors array, If it has same elements u need to omit that array elements and create a new element – Koushik Feb 20 '17 at 11:11

2 Answers2

2

it can be done easier:

func validateColor(color: UIColor) -> Bool {
    return !colors.contains(color)
}

or if you want to add some threshold for equality, then you could do something like this: The extension is taken from Extract RGB Values From UIColor

extension UIColor {
    var components: (red: CGFloat, green: CGFloat, blue: CGFloat, alpha: CGFloat)? {
        var r: CGFloat = 0, g: CGFloat = 0, b: CGFloat = 0, a: CGFloat = 0
        return getRed(&r, green: &g, blue: &b, alpha: &a) ? (r,g,b,a) : nil
    }
}


func validateColor(color: UIColor) -> Bool {
    let maxDistance: CGFloat = 0.3
    guard let colorComponents = color.components else {
        return true
    }
    return !colors.contains { c in
        guard let components = c.components else {
            return false
        }

        let distance = abs(colorComponents.red - components.red) + abs(colorComponents.green - components.green) + abs(colorComponents.blue - components.blue)

        return distance < maxDistance
    }
}

Set the threshold in maxDistance variable or move it to a static member of your class for better readability.

Community
  • 1
  • 1
Dmitry
  • 2,837
  • 1
  • 30
  • 48
1

firstly, you'll always get the same colours on each run because drand48() generates the same sequence of numbers unless you seed it. See this answer on how to do that, but here is the code, using the current time for randomise the seed:

let time = UInt32(NSDate().timeIntervalSinceReferenceDate)
srand48(Int(time))
let number = drand48()

Secondly - you are comparing a totally random colour (effectively a number between 0 and nearly 17,000,000) and wondering why it never seems to match the first colour in your colour array? I think you should be amazed if it ever matched :-)

Community
  • 1
  • 1
Steve Ives
  • 7,894
  • 3
  • 24
  • 55