Alessign
Alessign

Reputation: 788

Swift - Check if Array<AnyObject> contains UIColor

I came across little problem, I was googling several hours, but couldn't find solution.

I store multiple types of values in an array - usually String and UIColor. In one of my functions, I need to check if another array contains certain String or UIColor. I never know ahead if it will contain one object or the other or both. My method below always picks up only the String, but never finds the UIColor, even though I am 100% sure it's there. Even "print" shows the color is present, but it always gets ignored.

How can I correctly check if an array contains UIColor please?

// roundItem comes from Array<AnyObject> and reads: UIDeviceRGBColorSpace 0.160784 0.501961 0.72549 1
let btnInfo: Array<AnyObject> = dict["btn\(key)"]!

if ((btnInfo as NSArray).containsObject(roundItem as AnyObject)) {

            correctAnswer += 1
        }

This code above will increment the count if the string is matching, but if the color is matching according to the "print" it will not increment, console print:

btnInfo: [UIDeviceRGBColorSpace 0.160784 0.501961 0.72549 1]

roundItem: UIDeviceRGBColorSpace 0.160784 0.501961 0.72549 1

I tried another version, but it crashes:

     for item in (btnInfo as NSArray) {

            if item is UIColor {

                print("is UIColor")

                if ((roundItem as! UIColor).isEqual( item as! UIColor)){
                    correctAnswer += 1
                }
            }
            else if  item is String{

                print("is String")

                if roundItem as! String == item as! String{
                    correctAnswer += 1
                }
            }
        }

Console print:

Could not cast value of type '__NSCFString' (0x10fa332c8) to 'UIColor' (0x11167a268).

I tried do extension with Equatable, but it is crashing also with AnyObject.

How can I compare the stored UIColors or how to convert the UIDeviceRGBColorSpace to another format please?

Upvotes: 0

Views: 588

Answers (3)

Alessign
Alessign

Reputation: 788

Thank you all for the effort, especially @appzYourLife - nice clean solution for sorting.

I found what was wrong. I put the two arrays in simple test and it turned out, that the "roundItem" was cast as a String, not as a UIColor, that's why it was ignored as UIColor each time. I was retrieving this array from NSUserDefaults and that's where the error message came from pointing on

Could not cast value of type '__NSCFString' (0x10fa332c8) to 'UIColor' (0x11167a268)

...as it was stored as a String. So I made few changes and stored the colors in dictionary as UIColor with string key, which I am comparing and it works now. If I test the code above with both arrays which are storing UIColors (not from NSUserDefaults), it works well, so it still can be used if someone finds it helpful.

Thanks again

Best, A.

Upvotes: 0

Luca Angeletti
Luca Angeletti

Reputation: 59526

Given an array like this

let list:[AnyObject] = ["Hello", UIColor.whiteColor(), 123, UIColor.redColor()]

Contains

You can check if list contains a given color

let result = list.contains { ($0 as? UIColor) == UIColor.whiteColor() }

Colors

You can extract the colors and put them into an array of UIColor(s)

let colors = list.flatMap { $0 as? UIColor }

[UIDeviceWhiteColorSpace 1 1, UIDeviceRGBColorSpace 1 0 0 1]

Color indexes

You can also extract the color indexes and put them into an array of Int(s)

let colorIndexes = list.enumerate().filter { $0.element is UIColor }.map { $0.index }

[1, 3]

Not colors

Finally you can also retrieve the elements that are not colors and put them into an array of AnyObject(s)

let notColors = list.filter { !($0 is UIColor) }

Thanks @dfri

[Hello, 123]

Upvotes: 2

vadian
vadian

Reputation: 285160

It looks like there is no guarantee that if item is UIColor roundItem is also UIColor so you might check

if item is UIColor && roundItem is UIColor { ...

Upvotes: 1

Related Questions