I'm trying to create a push-on-push-off-like button with custom images in Xcode4 for iOS.
The code I'm using is
- (IBAction)btnAll:(id)sender
{
UIButton *button = (UIButton *)sender;
button.selected = !button.selected;
}
That works fine for now.
But my problem is, that when I'm toggling on, I press it on, then it is popping off again and then finally on.
The app works, but that is really ugly, though.
I firstly set the "highlighted" image to on. So when I highlight the button, it is on and that popping to on. That works fine. But when I turn it off again, the problem is the same, in the reverse direction.
I tried to put that code:
- (IBAction)btnAll:(id)sender
{
UIButton *button = (UIButton *)sender;
if(button.selected)
{
[button setImage[UIImage imageNamed#"off.png"] forState:UIControlStateHighlighted];
}
else
{
[button setImage[UIImage imageNamed#"on.png"] forState:UIControlStateHighlighted];
}
button.selected = !button.selected;
}
But as long button.selected = !button.selected there is no difference.
So it won't make any change.
I also tried to trigger the IBAction on »Touch Down« but you can imagine how frustrating this will look like.
Has anybody got a solution for that problem?
Did anybody struggle with that one too?
Greets, thanks a lot
Julian
Don't manually switch the images around, just set the selected state's image in Interface Builder and swap the selected property over when the button is tapped.
I've had a similar problem to this before, the button works a little strangely when tapping. Try this code and let me know if it works
UIButton *button = (UIButton *)sender;
if(button.selected)
{
[button setImage:[UIImage imageNamed:#"off.png"] forState:UIControlStateHighlighted];
[button setImage:[UIImage imageNamed:#"off.png"] forState:UIControlStateSelected];
[button setImage:[UIImage imageNamed:#"off.png"] forState:UIControlStateHighlighted | UIControlStateSelected];
}
else
{
[button setImage:[UIImage imageNamed:#"on.png"] forState:UIControlStateHighlighted];
[button setImage:[UIImage imageNamed:#"on.png"] forState:UIControlStateSelected];
[button setImage:[UIImage imageNamed:#"on.png"] forState:UIControlStateHighlighted | UIControlStateSelected];
}
button.selected = !button.selected;
If (button.selected) {
[button setImage:[UIImage imageNamed:#"on.png"] forState:UIControlStateNormal];
} else {
[button setImage:[UIImage imageNamed:#"off.png"] forState:UIControlStateNormal];
}
When you tap and hold on a button the state is actually Highlighted & Selected so you need an image for both Highlight and selected state.
Agree with Jim, your code needs little modification as below...
[button setImage[UIImage imageNamed#"off.png"] forState:UIControlStateNormal];
[button setImage[UIImage imageNamed#"on.png"] forState:UIControlStateSelected];
Have two buttons created.
place buttons one above one.
Can set Default & Selected images using Custom Button option in design builder.
-(void)firstButtonClicked {
firstButton.hidden = YES;
secondButton.hidden = NO;
}
-(void)secondButtonClicked {
firstButton.hidden = NO;
secondButton.hidden = YES;
}
#Jim - when do u switch the isSelected state? isHighlighted gets called twice for every press. My hacked version of UIButton switch below : -
class ButtonSwitch: UIButton {
override func sendAction(_ action: Selector, to target: Any?, for event: UIEvent?) {
if allControlEvents == .touchUpInside {
isSelected.toggle()
}
super.sendAction(action, to: target, for: event)
}
}
Related
I am new to iOS development with SDK version 5.0 through XCode. In my application I need to change the title of my Button when is push it.
Suppose in normal state it is "unpushed". All what I need is that when I push it the button label should change to "pushed".
Hoping to get help soon!
Regards
This may help you.
[btn setTitle:#"Pushed" forState:UIControlStateSelected];
[btn setTitle:#"UnPushed" forState:UIControlStateNormal];
In the button action add the following code -
[Button setTitle:#"Pushed"];
please see the Control States
you can do it like this:
[button setTitle:#"pushed" forState:UIControlStateHighlighted];
-(IBAction)startSomething:(id)sender {
[sender setTitle:#"Hello" forState:UIControlStateNormal];
}
Or if you're wanting to toggle the name of the button, you can create a BOOL named "buttonToggled" (for example), and toggle the name this way:
-(IBAction)toggleButton:(id)sender {
if (!buttonToggled) {
[sender setTitle:#"Unpushed" forState:UIControlStateNormal];
buttonToggled = YES;
}
else {
[sender setTitle:#"pushed" forState:UIControlStateNormal];
buttonToggled = NO;
} }
I have implemented a radio button on one of my apps, exactly like this solution:
http://www.developers-life.com/radio-buttons-in-iphone-application.html
but my checkboxButton method is like this:
- (IBAction)checkboxButton:(UIButton *)button{
for (UIButton *but in self.arrayButtons) {
if (but == button)
[but setSelected:YES];
else
[but setSelected:NO];
}
}
I have two buttons belonging to the same radio button group. When I select one of the buttons its image toggles to the switched one. Perfect. The problem is that when I select the other one it will not select to selected state and the first one that is being displayed as selected continues to be displayed as selected.
any clues?
for (UIButton *but in [Your_View subviews]) {
if ([but isKindOfClass:[UIButton class]] && ![but isEqual:button]) {
[but setSelected:NO];
}
}
if (!button.selected) {
button.selected = !button.selected;
}
why are you using so much complicated just use below to make selected..
- (IBAction)checkboxButton:(UIButton *)button
{
button.selected = !button.selected;
}
and make sure your images for button are set in the xib for each state as required.
In order to achieve the desired functionality, you will have to do selection of buttons in the next run loop.
So, call another method from "checkboxButton:".
Do something like,
- (IBAction)checkboxButton:(UIButton *)button
{
[self performSelector:#selector(highlighButton:) withObject:button afterDelay:0.0];
}
Where "highlightButton:" is defined as:
-(void) highlighButton:(UIButton*)aButton
{
[aButton setHighlighted:YES];
for (UIButton* button in self.arrayButtons) {
if (button != aButton) {
[button setHighlighted:NO];
}
}
}
I just made a few slight tweaks, and I just tested this and it works.
viewDidLoad: //making sure all buttons have the same selector assigned
[button1 addTarget:self action:#selector(checkboxButton:) forControlEvents:UIControlEventTouchUpInside];
[button2 addTarget:self action:#selector(checkboxButton:) forControlEvents:UIControlEventTouchUpInside];
[button3 addTarget:self action:#selector(checkboxButton:) forControlEvents:UIControlEventTouchUpInside];
Then just slightly modifying the loop to scan for button subviews instead of objects in an arbitrary array (should be more accurate)
- (IBAction)checkboxButton:(UIButton *)button{
for (UIButton *but in self.view.subviews) {//Change "self.view" to what ever view you are adding these subviews to.
if (but == button){
[but setSelected:YES];
}else{
[but setSelected:NO];
}
}
}
Keep in mind the selected state image/text that you are assigning will not appear until the button is released. When the button is pressed before it is released it is in its highlighted state. This is just a note so you can set this up accordingly.
After trying all solutions given here and have all failed, I tried a new approached and it worked perfectly.
The solution was to change this
- (IBAction)checkboxButton:(UIButton *)button{
for (UIButton *but in self.arrayButtons) {
if (but == button)
[but setSelected:YES];
else
[but setSelected:NO];
}
}
to this
- (IBAction)checkboxButton:(UIButton *)button{
for (UIButton *but in self.arrayButtons) {
if (but == button)
[but setImage:selectedImage forState:UIControlStateNormal];
else
[but setImage:normalImage forState:UIControlStateNormal];
}
}
apparently, changing the state of the button will not change its image. At least did not work for me.
I have an UIButton, I need to change button's image when button is tapped. Button's background images are set in ViewDidLoad method. Pls refer images attached on this thread.
When I tap on button first time, button property will be changed to selected and "arrow_right.png" image will be set to our Button.
2.On second tap, I observed that when button state is highlighted, But it's background image is not setting. You can see some blur effect instead.
My concern is I saw while toggling UIButton, image is not getting set for highlighted state. when button's state changing from Selected to Normal.
Is it a bug or my mistake?
Thank you.
- (void)viewDidLoad
{
[super viewDidLoad];
[testButton setBackgroundImage:[UIImage imageNamed:#"btn_normal.png"] forState:UIControlStateNormal];
[testButton setBackgroundImage:[UIImage imageNamed:#"btn_pressed.png"] forState:UIControlStateSelected];
[testButton setBackgroundImage:[UIImage imageNamed:#"btn_pressed.png"] forState:UIControlStateHighlighted];
}
- (IBAction)buttonPressed:(id)sender
{
UIButton *button = (UIButton*)sender;
button.selected = !button.selected;
if (button.selected)
{
[button setImage:[UIImage imageNamed:#"arrow_right.png"] forState:UIControlStateNormal];
[button setImage:[UIImage imageNamed:#"arrow_right.png"] forState:UIControlStateHighlighted];
[button setImage:[UIImage imageNamed:#"arrow_right.png"] forState:UIControlStateSelected];
}
else
{
[button setImage:[UIImage imageNamed:#"arrow_left.png"] forState:UIControlStateNormal];
[button setImage:[UIImage imageNamed:#"arrow_left.png"] forState:UIControlStateHighlighted];
[button setImage:[UIImage imageNamed:#"arrow_left.png"] forState:UIControlStateSelected];
}
}
try this
- (IBAction)buttonPressed:(id)sender
{
UIButton *button = (UIButton*)sender;
if(button.selected) {
[button setSelected:NO]
} else {
[button setSelected:YES]
}
}
i diddn't understand why you need to set image again, all you need to do is set its selected property , button will behave as you expected
I have following code and when I call this method, it doesn't change the image of the button although there are images in the resources.
-(void)changeButton:(NSString*)button withURL:(NSString*)url {
timetableURL = url;
UIImage *btnImage;
if ([button isEqual:#"Browser"]) {
btnImage = [UIImage imageNamed:#"browser-button.png"];
[safariBtn addTarget:self action:#selector(onSafariButtonPress:) forControlEvents:UIControlEventTouchUpInside];
}
else if ([button isEqual:#"Timetable"]) {
btnImage = [UIImage imageNamed:#"browser-timetable.png"];
[safariBtn addTarget:self action:#selector(onTimetableButtonPress:) forControlEvents:UIControlEventTouchUpInside];
}
[safariBtn setImage:btnImage forState:UIControlStateNormal];
[btnImage release];
}
UPDATED
FYI: It's a button upside UIToolbar.
Some things that seem to be wrong with your code:
[btnImage release]
You've created that image using autorelease, you are not responsible for its release. This will most likely end up in weird stuff happening, i.e. what you encountered.
Are you sure that btnImage has contents after that if statement? is there a possibility that button is not equal to #"Browser" nor #"Timetable"?
Also, make sure the button is in its normal state.
Cheers
Try This ,
[safariBtn setBackgroundImage:btnImage forState:UIControlStateNormal];
No need to release btnImage ...
i think this should help you...
[safariBtn setImage:[UIImage imageNamed:#"browser-button.png"] forState:UIControlStateNormal];
may be this will help you : set the titles of button where you created it and then control if it equals the title.
[safariBtn setTitle:#"Safari" forState:UIControlStateNormal];
then control
-(void)changeButton:(NSString*)button withURL:(NSString*)url {
timetableURL = url;
UIImage *btnImage;
if ([button titleForState:UIControlStateNormal] isEqualToString:#"Safari"]) {
btnImage = [UIImage imageNamed:#"browser-button.png"];
[safariBtn addTarget:self action:#selector(onSafariButtonPress:) forControlEvents:UIControlEventTouchUpInside];
}
else if ([button titleForState:UIControlStateNormal] isEqualToString:#"Timetable"]) {
btnImage = [UIImage imageNamed:#"browser-timetable.png"];
[safariBtn addTarget:self action:#selector(onTimetableButtonPress:) forControlEvents:UIControlEventTouchUpInside];
}
[safariBtn setImage:btnImage forState:UIControlStateNormal];
[btnImage release];
}
Change
[button isEqual:#"Browser"]
To
[button isEqualToString:#"Browser"]
isEqual is testing for object equality, not string equality.
EDIT: OK, you say your button is inside a toolbar. In this case I assume you have added it as a customview to a UIBarbuttonItem? You need to go through the bar button item and set the image property on the custom view of the bar button item, I think (though I'm not sure) once you've added a button as a custom view, the bar button item makes it's own copy so you are not talking to it any more via safariBtn.
You can access the toolbar items via
for (UIBarButtonItem *barItem in self.toolbar.items)
Assuming this code is in your viewController. Your safariBtn will then be accessible via barItem.customView
I am trying to make a standard check box for my iPhone app from a UIButton with a title and image. The button image changes between an "unchecked" image and a "checked" image.
At first I tried subclassing UIButton but UIButton has no -init*** method to use in my -init method.
What is the best way to do this?
Thanks in advance.
You shouldn't need to subclass the UIButton class. By design, Objective-C favors composition over inheritance.
UIButton is a subclass of UIControl, which has a selected property. You can use this property to toggle the on/off behaviour of a checkbox, just the same way a UISwitch does.
You can attach an action to the button's touched up inside event, and perform the toggling in there, something like this:
// when you setup your button, set an image for the selected and normal states
[myCheckBoxButton setImage:checkedImage forState:UIControlStateSelected];
[myCheckBoxButton setImage:nonCheckedImage forState:UIControlStateNormal];
- (void)myCheckboxToggle:(id)sender
{
myCheckboxButton.selected = !myCheckboxButton.selected; // toggle the selected property, just a simple BOOL
}
Set the images in the button:
[button setImage:uncheckedImage forState:UIControlStateNormal]
[button setImage:checkedImage forState:UIControlStateSelected]
Now all you need to do is:
button.selected = state
and the correct images will display.
All you need to do is set 2 different images for the states UIControlStateNormal and UIControlStateSelected, then in your selector, changed the selected property of the button.
Here is a working example (replace image names with your own):
- (void)loadView {
// ...
UIButton *chkBtn = [UIButton buttonWithType:UIButtonTypeCustom];
[chkBtn setFrame:CGRectMake(0, 0, 300, 25)];
[chkBtn setImage:[UIImage imageNamed:#"UNCHECKED.png"]
forState:UIControlStateNormal];
[chkBtn setImage:[UIImage imageNamed:#"CHECKED.png"]
forState:UIControlStateSelected];
[chkBtn addTarget:self
action:#selector(chkBtnHandler:)
forControlEvents:UIControlEventTouchUpInside];
// Optional title change for checked/unchecked
[chkBtn setTitle:#"I am NOT checked!"
forState:UIControlStateNormal];
[chkBtn setTitle:#"I am checked!"
forState:UIControlStateSelected];
[self.view addSubview:chkBtn];
[chkBtn release], chkBtn = nil;
// ...
}
- (void)chkBtnHandler:(UIButton *)sender {
// If checked, uncheck and visa versa
[sender setSelected:!sender isSelected];
}
For anyone interested in the future - instead of doing it yourself just download the link below from GitHub and it has it subclassed from UIControl already and functions perfectly as a checkbox. Also includes a sample project on how easy it is to use:
https://github.com/Brayden/UICheckbox
I have used M13Checkbox in one of my projects. Works ok.
https://github.com/Marxon13/M13Checkbox
Did you try overriding the initWithCoder method, just in case it is loaded from a nib somehow?
UIImage* nonCheckedImage=[UIImage imageNamed:#"ic_check_box_outline_blank_grey600_48dp.png"];//[UIImage init
UIImage* CheckedImage=[UIImage imageNamed:#"ic_check_box_black_48dp.png"];//[UIImage init
//ic_check_box_black_48dp.png
[_checkBox setImage:CheckedImage forState:UIControlStateSelected];
[_checkBox setImage:nonCheckedImage forState:UIControlStateNormal];
}
- (IBAction)checkBoxToggle:(id)sender {
_checkBox.selected = !_checkBox.selected; // toggle the selected property, just a simple BOOL
}
the image you can use google icon
Try this:-
-(IBAction)clickCheckButton:(UIButton *)sender {
if (sender.tag==0) {
sender.tag = 1;
[sender setImage:[UIImage imageNamed:#"check.png"] forState:UIControlStateNormal];
}else
{
sender.tag = 0;
[sender setImage:[UIImage imageNamed:#"uncheck.png"] forState:UIControlStateNormal]; } } sender.tag = 0;
[sender setImage:[UIImage imageNamed:#"uncheck.png"] forState:UIControlStateNormal];
}
}
Why not use a switch - UISwitch? This is used to display an element showing the boolean state of a value.