how to get all UILabels within a UIView
Asked Answered
N

4

7

I need a way to get all UILabels within a UIView without having to go through all the views within the UIView.

I have many other type of views, UIButtons, UIImageViews and it would be too long to go through all of them when I just need the UILabels.

I'm trying to avoid something like this:

for (UIView *view in myView.subviews) 
{
    if([view isKindOfClass:[UILabel class]])
    {
        UILabel *lbl = (UILabel*)view;
    }
}

Is it possible or am I dreaming?

Nestornestorian answered 12/4, 2012 at 16:52 Comment(1)
How do you create them - in Interface Builder or in code?Commorancy
C
6

Create an NSArray ivar which you can add all the UILabel's to.

If you do it in code then as you create the UILabel just do

NSMutableArray *labels = [[NSMutableArray alloc] init];

// Repeat this for al labels
UILabel *label = [[UILabel alloc] in...
[labels addObject:label];

// Then
self.labels = [labels copy];

If you use IB the declare your property like this

@property (nonatomic, strong) IBOutletCollection(UILabel) NSArray *labels;

and connect all the labels up to this.

Commorancy answered 12/4, 2012 at 17:1 Comment(1)
Not what I was looking for, but the best answer so far.Nestornestorian
E
4

Man, you need make use recursion. (If you don't want use tags)

Try This.

-(UIView *)checkChild:(UIView *)view{

    NSArray *arrayView = view.subviews;
    UIView *returnView = nil;

    for (UIView *auxView in arrayView) {
        if ([auxView isKindOfClass:[UILabel class]]) {
            return auxView;
        }else{
            returnView = [self checkChild:auxView];
        }
    }
    return returnView;
}
Ethelinda answered 15/1, 2014 at 22:33 Comment(1)
Nice snippet, you should just return an array of elements found on your path instead of returning a single element. You will also just get the last element from the subviews of the class you are looking for because you always overwrite the last element with a new value.Lustihood
L
2

I liked the approach of @SiddharthaMoraes, but changed it to collect all the elements found on its path. I was looking for the UILabels inside my UIViewController and couldn't find them because they where nested inside another UIView, so this recursion should solve the problem:

-(NSMutableArray *)checkChild:(UIView *)view{

    NSArray *arrayView = view.subviews;
    NSMutableArray *arrayToReturn = [NSMutableArray new];

    for (UIView *auxView in arrayView) {
        if ([auxView isKindOfClass:[MyLabel class]]) {
            [arrayToReturn addObject:auxView];
        }else if( auxView.subviews ){
            [arrayToReturn addObjectsFromArray:[self checkChild:auxView]];
        }
    }
    return arrayToReturn;
}
Lustihood answered 16/5, 2015 at 21:52 Comment(0)
S
1

You can set the tag property for the label.. something like this...

label.tag = 100;

UILabel *lbl = [yourView viewWithTag:100];
Sixpence answered 12/4, 2012 at 16:56 Comment(4)
Yuk don't use viewWithTag: there are much better waysCommorancy
@Commorancy : thank you for the comment.. May I know what is the disadvantage of using viewWithTag?Sixpence
FYI I was going to down vote, but I decided it would be a bit harsh as I see this suggestion a lot. It's just a bit naff/lazy - if you need a reference to a view and you know you need it, then why not make an ivar out of it? I don't like the idea of trawling through a potentially large view hierarchy asking each tag for an arbitrary value that can accidentally be changed. Also in the this case the OP wanted multiple views returned, which this API would not do.Commorancy
Its just a single UILabel, the question was, how to change many views once. OfftopicLustihood

© 2022 - 2024 — McMap. All rights reserved.