Liam
Liam

Reputation: 429

Accessing a UILabel via string Xcode identifier

If I have a UILabel on a viewcontroller, and have connected it to my swift class from the vc:

class RoomScheduleViewController: UIViewController {   
    @IBOutlet weak var bookingLabel8: UILabel!

How can I access this in a method? Like this:

    let hour = 8
    let labelToChange = "bookingLabel" + String(hour)

//Manipulate label e.g. labeltoChange.text = ".."

Also have an array like this: let

bookingLabelArray : [UILabel] = [bookingLabel8, bookingLabel9, bookingLabel10, bookingLabel11,bookingLabel12]

, was going to try loop through and check if the string is equal to the identifier but not sure how to do this?

Upvotes: 0

Views: 1764

Answers (7)

Tomasz Rejdych
Tomasz Rejdych

Reputation: 434

If you set tag for labels you can access to label without IBOutlet. Then you can do something like that:

func label(for hour: Int) -> UILabel? {
    return view.viewWithTag(hour) as? UILabel
}

let hour = 8 // bookingLabel8 needs tag 8
let labelToChange = label(for: hour)
labelToChange?.text = ".."

NOTE: this is simple but a dangerous solution because you can set the same tag for multiple subviews

Upvotes: 0

vadian
vadian

Reputation: 285039

You cannot compose variable names at runtime.

A possible solution is to declare the labels as IBOutletCollection

@IBOutlet weak var bookingLabels: [UILabel]!

Connect all labels in Interface Builder to this outlet in the proper order

Then add a method to get the label for index (assuming label 8 is the first label in the collection)

func label(for hour: Int) -> UILabel? { 
   let index = hour - 8
   guard 0..<bookingLabels.count ~= index else { return nil }
   return bookingLabels[index]
}

Upvotes: 1

B K.
B K.

Reputation: 534

let hour = int ()
hour = 8

let bookingLabelArray = NSMutableArray()
let labelToChange = UILabel()

for i in 0..<4 // count till you want.. here take 4
{
   labelToChange = "bookingLabel" + String(hour + i)
   bookingLabelArray .add(labelToChange)


   //You can directly check label text
   if labelToChange.text == "yourIdentifier" {
        // do whatever you want.
    }


 // You can check from array
   if((bookingLabelArray.object(at: i) as! String) == "yourIdentifier" {
        // do whatever you want.
    }


}

Upvotes: 0

nikksindia
nikksindia

Reputation: 1177

You can do this using IBOutlet Collections. For that you need to make 'outlet collection' instead of IBOutlet like:

 @IBOutlet weak var bookingLabel: [UILabel]!

and later you can access them using index like an array. For example:

bookingLabel[8].text = "some text"

To make an outlet connection, select outlet collection for first label from interface builder and the connect each label to this outlet.

For more details on IBOutlet collections, follow this link: Outlet Collections

Upvotes: 0

VetusSchola
VetusSchola

Reputation: 41

Can't comment so I'll ask my questions while trying to answer.

For accessing your label in a method, you can just use the label like so:

bookingLabel8.text = "..."

But seeing as you hold an array of those labels I assume you mean a dynamic way of updating the text of a given label.

For that you can pass the label to the method as a param, like so:

func change(label: UILabel, to text: String) {
  label.text = text
}

that way you can call this function for whichever label you want, and use a loop to iterate over your labels and check on the identifier for which one you want to change:

change(label: bookingLabelArray[0], to: "new text")

but this seems like a weird way to do this, are you sure you need those labels as static UI components? This seems to be more of a use case for dynamic prototypes in a list/collection view. There are plenty of tutorials out there, this seems to be a good one Prototype Cells

Upvotes: 1

Andreas Oetjen
Andreas Oetjen

Reputation: 10199

You could use a dictionary to map the "hour" to the label, e.g.

let labels = [8: bookingLabel8, 9: bookingLabel9 /* and so on */]

let hour = 8
if let labelToChange = labels[hour] {
    // do something
} 

Upvotes: 1

emrepun
emrepun

Reputation: 2666

You can do this with a for each loop:

If I understand correctly you want to catch the label with a certain text, lets call that certain text "your identifier":

bookingLabelArray.forEach { (label) in
        if label.text == "your identifier" {
            // do something with that label.
        }
    }

Upvotes: 0

Related Questions