1

Ok so Swift is great in may areas, and not so great in some.

I am trying to find an element in one array, based on the array from another array.

I have a few visual elements in my app that I need to hide and show sometimes, and instead of writing manual logic to show and hide the visual elements, I instead put them all in an array and call a function needs a reference array which contains the elements that I want to hide.

For example: I have 10 buttons (or a mix of different objects, such as UIImageViewsand UILabelsetc), we can call them B1 though B10.

If I at some point need to hide ALL elements EXCEPT B3, B4, B7, B9 and B10, I simply call hideAllExcept(ignore: Array<AnyObject>)(} and the func handles the rest.

Which elements that are hidden and shown can be completely random at times, so this approach can be very powerful.

However, when trying to check if an element from the first array contains in the second array I get the following error: Cannot invoke 'contains' with an argument list of type '(anObject: AnyObject)

How can I achieve this effect in Swift 2.1?

My current attempt looks like this (not working, obviously):

class myCollectionOfThings : UIView {
    let B1  = UIButton(type: UIButtonType.Custom)
    let B2  = UIButton(type: UIButtonType.Custom)
    let B3  = UIButton(type: UIButtonType.Custom)
    let B4  = UIButton(type: UIButtonType.Custom)
    let B5  = UIButton(type: UIButtonType.Custom)
    let B6  = UIButton(type: UIButtonType.Custom)
    let B7  = UIButton(type: UIButtonType.Custom)
    let B8  = UIButton(type: UIButtonType.Custom)
    let B9  = UIButton(type: UIButtonType.Custom)
    let B10 = UIButton(type: UIButtonType.Custom)

    var elements = Array<AnyObject>()

    func prep(parent: UIView){
        elements = [B1, B2, B3, B4, B5, B6, B7, B8, B9, B10]

        //I will be setting up all my UIButtons by code here...
    }

    func hideAllExcept(ignoreElements: Array<AnyObject>){
        var hide = Bool()

        for i in  0...ignoreElements.count - 1{
            if elements.contains(ignoreElements[i]){ //I get the error here
                //Hide the element here
            }
        }
    }
}
4
  • Since you know exactly that the array contains UIButton instances, why do you declare elements as AnyObject? Commented Oct 13, 2015 at 4:11
  • 1
    @vadian In the question he notes that he wants to have a mix of types, not just UIButton. Commented Oct 13, 2015 at 4:32
  • 1
    @Charles A.: UILabel, UIImageView and UIButton are all subclasses of UIView, so UIView like in your answer is much better than AnyObject Commented Oct 13, 2015 at 4:45
  • 1
    @vadian Agreed (obviously, given my answer). I thought you were suggesting he use a collection of UIButton type. Commented Oct 13, 2015 at 4:46

2 Answers 2

8

I do not believe the contains method of Swift arrays works like that. The contains method you're calling takes a block that will be invoked for every element in the array, and it's up to you to return a Bool if the element matches.

Have you considered using a Set? It seems like an easier approach given the properties and functions available on a Set. Note that you will have to declare it of a type that adopts the Hashable protocol, but it seems like you'd want to use UIView as your type anyhow if you want to hide your elements (hidden is declared on UIView).

class myCollectionOfThings : UIView {
    let B1  = UIButton(type: UIButtonType.Custom)
    let B2  = UIButton(type: UIButtonType.Custom)
    let B3  = UIButton(type: UIButtonType.Custom)
    let B4  = UIButton(type: UIButtonType.Custom)
    let B5  = UIButton(type: UIButtonType.Custom)
    let B6  = UIButton(type: UIButtonType.Custom)
    let B7  = UIButton(type: UIButtonType.Custom)
    let B8  = UIButton(type: UIButtonType.Custom)
    let B9  = UIButton(type: UIButtonType.Custom)
    let B10 = UIButton(type: UIButtonType.Custom)

    var elements = Set<UIView>()

    func prep(parent: UIView){
        elements = [B1, B2, B3, B4, B5, B6, B7, B8, B9, B10]

        //I will be setting up all my UIButtons by code here...
    }

    func hideAllExcept(ignoreElements: Set<UIView>){
        for element in elements.subtract(ignoreElements) {
            element.hidden = true
        }
    }
}

You may also want to set elements in ignoreElements to not be hidden, unless you do that somewhere else. You could easily do that with:

for element in ignoreElements {
    element.hidden = false
}
Sign up to request clarification or add additional context in comments.

Comments

1

First of all, you should use NSObject instead of AnyObject. like:

var elements = Array<NSObject>()

In your case, i think use Set would be better. here's the snippet:

import UIKit

class myCollectionOfThings : UIView {

    typealias ButtonSet = Set<UIButton>   // More readability for collections

    let B1  = UIButton(type: UIButtonType.Custom)
    let B2  = UIButton(type: UIButtonType.Custom)
    let B3  = UIButton(type: UIButtonType.Custom)
    let B4  = UIButton(type: UIButtonType.Custom)
    let B5  = UIButton(type: UIButtonType.Custom)
    let B6  = UIButton(type: UIButtonType.Custom)
    let B7  = UIButton(type: UIButtonType.Custom)
    let B8  = UIButton(type: UIButtonType.Custom)
    let B9  = UIButton(type: UIButtonType.Custom)
    let B10 = UIButton(type: UIButtonType.Custom)

    var buttons = ButtonSet()

    func prep(parent: UIView){
        buttons = [B1, B2, B3, B4, B5, B6, B7, B8, B9, B10]

        //I will be setting up all my UIButtons by code here...
    }

    func hideAllExcept(ignoreElements: ButtonSet) {
        let exceptions = buttons.subtract(ignoreElements)
    }
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.