Home > Back-end >  Managing multiple UIViews names into switch...case Swift statement
Managing multiple UIViews names into switch...case Swift statement

Time:01-15

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

CodePudding user response:

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)

CodePudding user response:

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
            }
        }()
    }  
}

CodePudding user response:

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!")
        }
    }
  •  Tags:  
  • Related