Eduardo Bonfa
Eduardo Bonfa

Reputation: 288

How to compare a random UIColor to colors in an array of colors in swift?

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?

Upvotes: 2

Views: 868

Answers (2)

Dmitry
Dmitry

Reputation: 2887

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.

Upvotes: 2

Steve Ives
Steve Ives

Reputation: 8134

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 :-)

Upvotes: 1

Related Questions