Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

mistergreen2011

macrumors member
Original poster
Mar 23, 2011
36
0
So I'm trying to change a button's title after it has been added into another view. A gave it a tag so I can call it but it's not working.

Button code
Code:
 //button
    CGRect frame = CGRectMake(100.0, 70.0, 100.0, 35.0);
    UIImage *blueImage = [UIImage imageNamed:@"blue_button.png"];
    UIImage *blueButtonImage = [blueImage stretchableImageWithLeftCapWidth:7 topCapHeight:0];
    
    UIButton *btn = [[UIButton alloc] initWithFrame:frame];
    
    [btn setTitle:@"CaSO4" forState:UIControlStateNormal];
    [btn setTitleColor:[UIColor blackColor] forState:UIControlEventTouchDown];
    btn.titleLabel.font = [UIFont boldSystemFontOfSize:12.0];
    [btn setTitleEdgeInsets:UIEdgeInsetsMake(0.0, 0.0, 0.0, 10.0)];
    [btn setBackgroundImage:blueButtonImage forState:UIControlStateNormal];
    btn.contentVerticalAlignment = UIControlContentVerticalAlignmentCenter;
    btn.contentHorizontalAlignment = UIControlContentHorizontalAlignmentCenter;
    [btn addTarget:self action:@selector(slideButton:) forControlEvents:UIControlEventTouchUpInside];
    btn.tag = 102;
    [self.view addSubview:btn];
    [btn release];

Method to change the title
Code:
- (void)setButton:(NSString *)label
{
    [[self.view viewWithTag:102] setTitle:label forState:UIControlStateNormal];
    
}

The warning is 'UIView' may not respond to 'SetTitle:forState'
Which is true... I'm trying to target the button and not the view.

thanks.
 

robbieduncan

Moderator emeritus
Jul 24, 2002
25,611
893
Harrogate
Assuming that there is only ever one view with tag 102 then you can just case the result to the correct type. Given that you've not done that already I'll assume you don't know what that means (sorry if you do). In general a cast looks like:

Code:
((MyType) var)

This tells the compiler to treat var as type MyType. Note that this does not actually change the type of var. If it's impossible to perform the cast then this will fail. In terms of object pointers you can suppress the compiler warning but still have runtime errors (for example you could cast and id typed var to any NSObject * subtype but it doesn't make var the correct object). So you should only do this when you are 100% sure your cast is correct.

In this case you want code that looks like this:

Code:
- (void)setButton:(NSString *)label
{
    [((UIButton *) [self.view viewWithTag:102]) setTitle:label forState:UIControlStateNormal];
    
}

I would note that there are ways to make this less brittle. You could check the class of the returned UIView (using a variable to store the view pointer). Or you could check if the UIView responds to the -setTitle:forState: message and send it via -performSelector:withObject:withObject:
 

dantastic

macrumors 6502a
Jan 21, 2011
572
678
Sometimes setting a tag with:

Code:
myButton.tag = 1;
does not actually set the tag properly but I'd have to do
Code:
[myButton setTag:1];
instead.

you could try
Code:
self.myButton.tag = 1;
 
Last edited:

mistergreen2011

macrumors member
Original poster
Mar 23, 2011
36
0
I tried casting it. That got rid of the warning but the button title doesn't change.

Code:
- (void)setButton:(NSString *)label
{
   
    [((UIButton *)[self.view viewWithTag:102]) setTitle:label forState:UIControlStateNormal];
   
    if([self.view viewWithTag:102]) {
        NSLog(@"I exist");
    }
    
    NSLog(@"%@", label);
}

I even checked to see if view tag:102 exists, which it does :)

I'll try the saving the view to a pointer and performSelector suggestions next.
 

robbieduncan

Moderator emeritus
Jul 24, 2002
25,611
893
Harrogate
I'll try the saving the view to a pointer and performSelector suggestions next.

That won't make any difference. That was simply a suggestion on style/modularity. You're check that the view with tag 102 is incorrect. You should be doing:

Code:
 if([self.view viewWithTag:102]!=nil) {
        NSLog(@"I exist");
    }
 

ppilone

macrumors 6502
Jan 20, 2008
361
0
Also, when dealing with UIButton it's usually best to create one in code using:

Code:
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];

You can replace the button type with whichever type you need (e.g. UIButtonTypeRoundedRect). Make sure you set the frame of the button after initializing a new one.
 

mistergreen2011

macrumors member
Original poster
Mar 23, 2011
36
0
whoa, something really strange...
I modified it to this..

Code:
    if([self.view viewWithTag:102] != nil) {
        NSLog(@"I exist");
        UIButton *bttn = (UIButton *)[self.view viewWithTag:102];
        [bttn setTitle:label forState:UIControlStateNormal];
        NSLog(@"%@", [bttn titleForState:UIControlStateNormal]);
    }

I wanted to see what the title of the button is and the title on the button DOES change in code but not visually in the view. Does the view need to be refreshed or something?

EDIT:

Thanks for the help guys. I made a simpler project with these exact code and it works.... My bigger project must be breaking this somewhere. I'll have to dig through the code.


Update:

I found the problem. I'm calling this method 'setButton' from a pickerview in another view. I made a delegate to call setButton and it working's correctly now. It's weird that the method does get called normally with instantiating, [[myClass alloc] init] setButton] but needed a delegate to work correctly.
 
Last edited:
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.