Reputation: 753
I have a view controller with 100 IBOutlets that I want to hide or display depending on whether the name of that IBOutlet is found as a key in Dictionary.
How on earth do I do this? My intuition points me to
for item in Dict {
// try to refer to an IBOutlet using data from my Dictionary
self.\(item.key).hidden = false
}
Swift obviously throws up and error when I try to do this.
I'm new to this and not even sure what to call what I'm trying to do. Is it even possible to do this? Is there a much better way to do this?
I'd like to avoid writing 100 "if" statements.
Upvotes: 3
Views: 1055
Reputation:
I agree with Sulthan that this is a case were constraints and IB are poor design. I coded this up as a template the should help you out. Notes:
The code:
let width:CGFloat = 20
let height:CGFloat = 20
override func viewDidLoad() {
super.viewDidLoad()
create100subviews()
for view in view.subviews as [UIView] {
color(view)
}
}
func create100subviews() {
for i in 1...100 {
let newView = UIView(frame: calculateFrame(width: width, height: height, tag: i))
newView.tag = i
view.addSubview(newView)
}
}
func calculateFrame(width:CGFloat, height:CGFloat, tag:Int) -> CGRect {
let (row,column) = calculateRowAndColumn(tag: tag)
return CGRect(x: ((CGFloat(column)*width)+20), y: ((CGFloat(row)*height)+40), width: width, height: height)
}
func calculateRowAndColumn(tag:Int) -> (Int,Int) {
// the returned tuple (row,column) is zero-based
var row:Int = 0
var column = tag
while column > 10 {
row += 1
column -= 10
}
column -= 1
return (row,column)
}
func color(_ view: UIView) {
let (row,column) = calculateRowAndColumn(tag: view.tag)
var seedValue = column + row + 1
while seedValue > 10 {
seedValue -= 10
}
switch seedValue {
case 1:
view.backgroundColor = UIColor.black
case 2:
view.backgroundColor = UIColor.red
case 3:
view.backgroundColor = UIColor.green
case 4:
view.backgroundColor = UIColor.blue
case 5:
view.backgroundColor = UIColor.black
case 6:
view.backgroundColor = UIColor.red
case 7:
view.backgroundColor = UIColor.green
case 8:
view.backgroundColor = UIColor.blue
case 9:
view.backgroundColor = UIColor.black
case 10:
view.backgroundColor = UIColor.red
default:
break
}
}
Upvotes: 0
Reputation: 273898
There should be lots of other, better ways to do this.
Have you considered adding all the outlets to dictionary?
var outletDict: [String: UIView] = ["outlet1": outlet1, "outlet2": outlet2,
"outlet3", outlet3 ... "outlet100": outlet100]
Then you can just access the outlets using this dictionary:
for item in Dict {
outletDict[item.key].hidden = false
}
Have you tried not using outlets and dynamically create the views instead? I mean, it's really rare to have 100 outlets. I wonder how you connected them all. They should be in a pattern or something. If that's true, you can create your views with for loops and add them to the dictionary mentioned above.
If none of the above applies to you, the only solution I can think of is this:
for item in Dict {
let mirror = Mirror(reflecting: self)
let outlet = mirror.children.filter { $0.label == item.key }.first?.value as? UIView
outlet?.hidden = false
}
Upvotes: 2