Find UILabel in UIView in Swift
Asked Answered
S

4

11

I'm trying to find my UILabels in my superview of my UIViewControllers. This is my code:

func watch(startTime:String, endTime:String) {
    if superview == nil {println("NightWatcher: No viewcontroller specified");return}

    listSubviewsOfView(self.superview!)

}

func listSubviewsOfView(view: UIView) {
    var subviews = view.subviews

    if (subviews.count == 0) { return }

    view.backgroundColor = UIColor.blackColor()

    for subview in subviews {
        if subview.isKindOfClass(UILabel) {
            // do something with label..
        }
        self.listSubviewsOfView(subview as UIView)
    }
}

This is how it is recommended to in Objective-C, but in Swift I get nothing but UIViews and CALayer. I definitely have UILabels in the view that is supplied to this method. What am I missing?

The call in my UIViewController:

  NightWatcher(view: self.view).watch("21:00", endTime: "08:30") // still working on
Salience answered 20/8, 2014 at 19:8 Comment(4)
I tested this with Xcode 6b6 and it works: I am able to find a UILabel inside a UIView that is a subview of my viewController's view. Do you use Xcode 6b6? Do you use a Storyboard? When/how do you call this method?Zelma
Thanks for your reply. I use Xcode6b5, Storyboard. The method is placed in a seperate non-UI class and I call it from my UIViewController.Salience
In watch:, what do you get when you call listSubviewsOfView(view) instead of listSubviewsOfView(self.superview!)?Zelma
I have a variable in my class called: var superview:UIView?. I cannot call it as 'view'. The superview is thus the 'self.view'Salience
E
10

Using functional programming concepts you can achieve this much easier.

let labels = self.view.subviews.flatMap { $0 as? UILabel }

for label in labels {
//Do something with label
}
Esme answered 28/9, 2017 at 22:50 Comment(3)
Updated this to be the accepted answer as it applies for all code bases using Swift 2.0+. It's much cleaner and (arguable) more readable. Swift has come a long way :)Salience
I get Value of type 'UIView' has no member 'flatMap'Chorizo
@Chorizo If you are writing that code in the correct context it should work. Comment this code out and cmd+B. Do you see any errors? If not uncomment and cmd+B againEsme
L
11

Here's a version that will return an Array of all the UILabel views in whatever view you pass in:

func getLabelsInView(view: UIView) -> [UILabel] {
    var results = [UILabel]()
    for subview in view.subviews as [UIView] {
        if let labelView = subview as? UILabel {
            results += [labelView]
        } else {
            results += getLabelsInView(view: subview)
        }
    }
    return results
}

Then you can iterate over them to do whatever you'd like:

override func viewDidLoad() {
    super.viewDidLoad()

    let labels = getLabelsInView(self.view)
    for label in labels {
        println(label.text)
    }
}
Lindeberg answered 20/8, 2014 at 19:59 Comment(4)
This works just fine.. Thanks! I'll try to figure out what's wrongSalience
I'm running this in Swift 3.1 but it returns two objects, one of which is the label of a UIButton, not a UILabel in itself. Is there a way to make it more explicit?Pell
@Pell Same here. DId you find a better solution?Inappropriate
I'm doing this: for case let label as UILabel in view.subviews {...}Hazeghi
E
10

Using functional programming concepts you can achieve this much easier.

let labels = self.view.subviews.flatMap { $0 as? UILabel }

for label in labels {
//Do something with label
}
Esme answered 28/9, 2017 at 22:50 Comment(3)
Updated this to be the accepted answer as it applies for all code bases using Swift 2.0+. It's much cleaner and (arguable) more readable. Swift has come a long way :)Salience
I get Value of type 'UIView' has no member 'flatMap'Chorizo
@Chorizo If you are writing that code in the correct context it should work. Comment this code out and cmd+B. Do you see any errors? If not uncomment and cmd+B againEsme
O
1

Swift 4

Adepting mKane's answer you can use this code:

let labels = self.view.subviews.compactMap { $0 as? UILabel }

for label in labels {
   // do whatever
}
Ornithic answered 12/11, 2018 at 21:50 Comment(0)
B
1

You could set a tag to your UILabel in the Storyboard or programmatically using:

myLabel.tag = 1234 

Then, to find it use:

let myLabel = view.viewWithTag(1234)

Baldridge answered 30/11, 2018 at 9:35 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.