Kwangle Kwangle - 7 months ago 18
Swift Question

Swift: Dynamically targeting UI objects - UILabels, UIImageViews

I'm writing an app in Swift (XCode 6.4) that contains many UILabels and UIImageViews, eg:

@IBOutlet weak var image1: UIImageView!
@IBOutlet weak var image2: UIImageView!
@IBOutlet weak var image3: UIImageView!

@IBOutlet weak var label1: UILabel!
@IBOutlet weak var label2: UILabel!
@IBOutlet weak var label3: UILabel!
//many more


I want to be able to write functions that can dynamically target a label or image view simply by passing a parameter:

func setImage (num: Int) {
let imageView = "image" + String(num)
imageView.image = "myGraphicName"
}


Obviously this won't work as the imageView constant is just a string such as "image3". So how do I target the UI objects based on their name? There was something in ActionScript like:

eval["nameofobject"].width = 125;


This allowed string names to be linked to object, thus accessing its methods and parameters.

Many thanks for any help.

Kw.

Answer

If you need to target a specific item by number, one approach is to design a numbering scheme, and use tags instead of names.

For example, you could number all your UIImageViews starting at 1000, all your UILabels starting at 2000, all your UIButtons starting at 3000, and so on.

With these tags in place, rewrite your function as follows:

func setImage (tag: Int) {
    let imageView = self.view.viewWithTag(tag) as! UIImageView
    imageView.image = UIImage(named:"myGraphicName")
}

If you want to address a group of items in a loop, you could use @IBOutletCollection instead. Make an outlet collection, and add the desired UIImageView objects to it. When you need to perform the same action on all UIImageView objects, loop through all items in @IBOutletCollection with a for-each loop.

Comments