Toggle UIButton on the iPhone
How can I make a button that says "Show Picture" and when it's clicked it changes to "Hide Picture". I'm new to objective C, I know how to make a button in interface builder but don't know how to switch the 开发者_如何学Pythonbutton's text and function. Can someone help me out?
Don't abuse the tag property. It is advise only to be used as a button identifier (for example when you have few buttons in your view you set their tags as 0, 1, 2... so can identify which button is a sender). You could set some global int i variable and change it's value accordingly.
abuse the .tag property of the button. Hook up the touch down action to this function:
-(IBAction)buttonClick:(UIButton*)sender
{
if ( sender.tag )
{
sender.tag = 0;
sender.text = @"Show Picture";
// do actions when "hide" is clicked
} else {
sender.tag = 1;
sender.text = @"Hide Picture";
// do actions when "show" is clicked
}
}
Instead of (ab)using the tag property, you could also simply toggle the button between selected and not selected, like so:
- (IBAction)myButtonAction:(id)sender
{
[sender setSelected:![sender isSelected]];
// or in Objective-C 2.0 if you're so inclined
sender.selected = !sender.selected;
}
In IB, you could then set the text for the normal and the selected state of the button directly in the inspector (or programmatically through the setTitle:forState: method).
The tricky thing with this one is that a UIButton doesn't have an "official" text properly - see the docs here:
http://developer.apple.com/iphone/library/documentation/uikit/reference/UIButton_Class/UIButton/UIButton.html
because it's designed to have multiple, separate sets of texts, displayed according to the button's current state; i.e., whether it's currently enabled or disabled, highlighted, etc. So there's not one, simple property you can set to make this work.
So, you want to declare your button like this, as both an action and an outlet:
from button.h:
// inside the class declaration
BOOL pictureShown ; // initializer not required, defaults to 0 (NO)
UIButton * sampleButton ;
// skip irrelevant lines here
@property (nonatomic, retain) IBOutlet UIButton * sampleButton ;
- (IBAction) doSampleButton ;
Hook both of those up in Interface Builder, and then change the text using the setTitle:forState: method (and in this case, I've specified all the states, so the title stays the same across all of them). For example:
from button.m:
@synthesize sampleButton ;
- (IBAction) doSampleButton {
if (pictureShown == YES) {
// hide the picture, and then...
[sampleButton setTitle: @"Show Picture" forState: (UIControlStateNormal | UIControlStateHighlighted | UIControlStateSelected | UIControlStateDisabled)] ;
pictureShown = NO ;
} else {
// show the picture, and then...
[sampleButton setTitle: @"Hide Picture" forState: (UIControlStateNormal | UIControlStateHighlighted | UIControlStateSelected | UIControlStateDisabled)] ;
pictureShown = YES ;
}
}
You'll also note that I've declared an instance variable, "pictureShown", in the view controller for the view with the button, to track the current "mode" of the button, and that I'm essentially using an if statement inside the button's action to determine which function is carried out according to the current mode of the button, and to toggle the button text accordingly.
(I'm using this to track the current mode of the button rather than, for example, examining the current title of the button directly, or other ways of storing state on the button, because MVC-wise, this sort of state belongs in the controller class.)
(If the function required a lot of code, I'd use messages to self, i.e.:
[self showPicture] ;
[self hidePicture] ;
to avoid having to cram it all inside doSampleButton, but that's purely stylistic, rather than technically required.
精彩评论