n.evermind
n.evermind

Reputation: 12004

How to alter the text of an UILabel after having created it programmatically in a loop

I would like to create 10 buttons programmatically. Each button has a subview with two labels (one string and one integer).

After I have created these 10 buttons in a loop, I would like to access both labels. I tried to NSLog the labels of the button with tag 0, but it didn't work.

All of this feels a bit clumsy, so please correct me if I'm going nowhere with this:

for (int i = 0; i < 9; i++) {

    UIButton* btn = [[[UIButton alloc] initWithFrame:CGRectMake(55, i*(indexHeight+indexSpacing), indexWidth, indexHeight)] autorelease]; 
    btn.tag = i;
    [btn setBackgroundImage:nil forState:UIControlStateNormal];
    [btn    addTarget:self
            action:@selector(buttonTapped:)
  forControlEvents:UIControlEventTouchUpInside];

 // LABELS

    UILabel *btnTitle = [[[UILabel alloc] initWithFrame:CGRectMake(0, 0, indexWidth, indexHeight)] autorelease];
     btnTitle.text = @"Empty";

    UILabel *pageTitle = [[[UILabel alloc] initWithFrame:CGRectMake(190, 0, 30, indexHeight)] autorelease];
     pageTitle.text = @"x";

    [indexView addSubview:btn];
    [btn addSubview:btnTitle];
    [btn addSubview:pageTitle];
}

This is what I've tried and where my problem is:

NSLog (@"Accessing label 1 in button with tag 0 in indexView: '%@'", [[indexView viewWithTag:0] btnTitle.text]);
NSLog (@"Accessing label 2 in button with tag 0 in indexView: '%@'", [[indexView viewWithTag:0] pageTitle.text]);

"UILabel created programmatically - find it again?" is the closest question I could find, but it doesn't really answer the question of how to access labels in a subview of a btn.

Upvotes: 1

Views: 404

Answers (3)

Sid
Sid

Reputation: 9536

1

Add this ivar in your header file:

NSMutableArray *buttonArray;

 

2

Initialize this array in your .m file's init:

buttonArray = [NSMutableArray array];
[buttonArray retain];

 

3

Change your for loop as follows:

for (int i = 0; i < 9; i++) 
    {
        
        UIButton* btn = [[[UIButton alloc] initWithFrame:CGRectMake(55, i*(indexHeight+indexSpacing), indexWidth, indexHeight)] autorelease]; 
        btn.tag = i;
        [btn setBackgroundImage:nil forState:UIControlStateNormal];
        [btn    addTarget:self
                   action:@selector(buttonTapped:)
         forControlEvents:UIControlEventTouchUpInside];
        
        // LABELS
        
        UILabel *btnTitle = [[[UILabel alloc] initWithFrame:CGRectMake(0, 0, indexWidth, indexHeight)] autorelease];
        btnTitle.text = @"Empty";
        
        UILabel *pageTitle = [[[UILabel alloc] initWithFrame:CGRectMake(190, 0, 30, indexHeight)] autorelease];
        pageTitle.text = @"x";
        
        [indexView addSubview:btn];
        [btn addSubview:btnTitle];
        [btnTitle release]; //avoiding leaks
        [btn addSubview:pageTitle];
        [pageTitle release]; //avoiding leaks
        
        
        
        
        
        
        //The changes are here.....
        
        [buttonArray addObject:btn];
        [btn release];
    }

 

4

To access a button from your array do (button 5 for example):

UIButton *thisButton = (UIButton *)[buttonArray objectAtIndex:5];

 

5

Do whatever you want with this button :)

PS: You're allocating those btn objects inside a for loop (and seems like they aren't ivars). They will lose scope once you're outside the for loop so you won't be able to access them anyway. The above method for using an NSMutableArray addresses this problem also as now you've created the btn's and added them to an array which is an ivar so you don't lose scope outside the for loop. Furthermore, you should probably be subclassing UIButton if you want to have custom subviews on it.

Upvotes: 1

james_womack
james_womack

Reputation: 10316

The following for sure works if indexHeight,indexSpacing,indexWidth, are set.

for (int i = 0; i < 9; i++) {

    UIButton* btn = [[[UIButton alloc] initWithFrame:CGRectMake(55, i*(indexHeight+indexSpacing), indexWidth, indexHeight)] autorelease]; 
    btn.tag = i;
    [btn setBackgroundImage:nil forState:UIControlStateNormal];
    [btn    addTarget:self
            action:@selector(buttonTapped:)
  forControlEvents:UIControlEventTouchUpInside];

 // LABELS

    UILabel *btnTitle = [[[UILabel alloc] initWithFrame:CGRectMake(0, 0, indexWidth, indexHeight)] autorelease];
     btnTitle.text = @"Empty";

    btnTitle.tag = i+100;
    UILabel *pageTitle = [[[UILabel alloc] initWithFrame:CGRectMake(190, 0, 30, indexHeight)] autorelease];
     pageTitle.text = @"x";
     pageTitle.tag = i+101;

    [indexView addSubview:btn];
    [btn addSubview:btnTitle];
    [btn addSubview:pageTitle];

}

for (int i = 0; i < 9; i++) {
   UILabel *btnTitle = (UILabel *)[[indexView viewWithTag:i] viewWithTag:100+i];
   UILabel *pageTitle = (UILabel *)[[indexView viewWithTag:i] viewWithTag:101+i];
   NSLog (@"btnTitle.text: '%@'", btnTitle.text);
   NSLog (@"pageTitle.text: '%@'", pageTitle.text);

}

Upvotes: 1

arclight
arclight

Reputation: 5310

You could try assigning a tag to each of the labels too, something like 100 for the first one and 101 for the second one, then your code would look like this for retrieving the labels

NSLog (@"Accessing label 1 in button with tag 0 in indexView: '%@'", [[indexView viewWithTag:0] viewWithTag:100].text);
NSLog (@"Accessing label 2 in button with tag 0 in indexView: '%@'", [[indexView viewWithTag:0] viewWithTag:101].text);

Upvotes: 2

Related Questions