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
}
}
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!")
}
}

