skip to Main Content

I have a UIViewController with multiple UIViews named view0, view1, view2… After a parsing queue my app retrieve a parsedArray and must change single views background color depending on its value. To avoid long if…else routines I wanna use switch…case statement: so, what’s the best way to manage these multiple UIViews names into the switch…case statement? An extension? I know I could use Collection views or UIStackViews but I’ve already a lot of methods focused on single UIViews, and btw I’d like to learn the best way to manage multiple names in a type name like UIView. Thanks!

    func colorViews() {
    
    for i in 0...21
    {
        switch (parsedArray[i]) {
        case "0": viewX.backgroundColor = .systemRed // HERE X MUST BE i
        default:
             viewX.backgroundColor = .systemGreen // HERE X MUST BE i
        }

    }
    

enter image description here

3

Answers


  1. Chosen as BEST ANSWER

    As suggested by Joakim comment, the solution is easier than I thought: a simple Array of names, and I post it to further reference. Thank you to the other suggestions, I'll study better.

    In the controller scope:

    var views = [UIView]()
    

    In viewDidLoad() func:

    views = [view0, view1, view2, view3, view4, view5, view6, view7, view8, view9, view10, view0b, view1b, view2b, view3b, view4b, view5b, view6b, view7b, view8b, view9b, view10b]
    

    In the switch...case statement:

            for i in 0...21
        {
            switch (parsedArray[i]) {
            case "0":
                views[i].backgroundColor = .systemRed // HERE [i] CALLS SINGLE UIVIEW NAME!
            case "1":
                views[i].backgroundColor = .systemGreen // HERE [i] CALLS SINGLE UIVIEW NAME!
            default:
                print("DEFAULT!")
            }
        }
    

  2. one solution if you do not want to change your current structure, you can use view ids. When you generate your viewX’s, just add a id to it with the same value of the view’s number.

    This is a sample:

    extension UIView {
    
        var id: String? {
            get {
                return self.accessibilityIdentifier
            }
            set {
                self.accessibilityIdentifier = newValue
            }
        }
    
        func view(withId id: String) -> UIView? {
            if self.id == id {
                return self
            }
            for view in self.subviews {
                if let view = view.view(withId: id) {
                    return view
                }
            }
            return nil
        }
    }
    

    After that you can access your views like:

    let view = UIView.view(withId: 0)
    
    Login or Signup to reply.
  3. Either have your views placed in array or create a function that returns you a view for given index.

    An array approach looks like this:

    private var nodeViews: [UIView] {
        return [
            view0, view1, view2, view3, view4, view5,
            view6, view7, view8, view9, view10, view11,
    
            view12, view13, view14, view15, view16, view17,
            view18, view19, view20, view21, view22, view23
        ]
    }
    

    and you would have your method like

    private func refreshNodeColors() {
        let nodes = self.nodeViews
        parsedArray.enumerated().forEach { index, value in
            guard index < nodes.count else { return } // More data in array than nodes supported
            nodes[index].backgroundColor = {
                switch value {
                    case "0": return .systemRed
                    default: return .systemGreen
                }
            }()
        }  
    }
    

    A function that returns a view with index would look like so

    private func nodeWithIndex(_ index: Int) -> UIView? {
        switch index {
            case 0: return view0
            case 1: return view1
            // TODO: add other views here as well
            default: return nil
        }
    }
    

    and you would use it like so

    private func refreshNodeColors() {
        parsedArray.enumerated().forEach { index, value in
            guard let node = nodeWithIndex(index) else { return } // Node with this index does not exist
            node.backgroundColor = {
                switch value {
                    case "0": return .systemRed
                    default: return .systemGreen
                }
            }()
        }  
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search