How to make Uibutton selected - ios

I have a UIButton which remains selected when I select that button. Here is my code:
- (IBAction)cloudclick:(UIButton *)sender {
UIImage *bgImage = [UIImage imageNamed:#"black_cloud.png"];
UIButton *tmpButton = (UIButton *)[self.view viewWithTag:sender.tag];
[tmpButton setBackgroundImage:bgImage forState:UIControlStateSelected];
}
But it does not remain selected when I click the button. It changes the background but it does not remain as selected button.

you have to write one line after your code
- (IBAction)cloudclick:(UIButton *)sender {
...
[tmpButton setSelected:YES];
}

use this line of code
sender.selected=!sender.selected;
and set different image for diff states at the time alloc if you are making button from code otherwise set images from xib's.

The various states: UIControlStateNormal, UIControlStateSelected, and (UIControlStateSelected | UIControlStateHighlighted) are all actually distinct. If you want your shadowImage to apply both in the (only) highlighted state and in the highlighted+selected state, you must also set:
[button setBackgroundImage: bgImage forState:(UIControlStateHighlighted | UIControlStateSelected)]

in Swift 5
sender.isSelected.toggle()

Related

Blue image for buttons

I have buttons in my costoum cell , and i'm setting the images from code . But something strange is happening. My images are blue .
BOOL isTheObjectThere = [self.favoriteArry containsObject:self.tableData[indexPath.row]];
if (isTheObjectThere==TRUE) {
cell.favBtn.hidden = NO;
[cell.favBtn setImage:[UIImage imageNamed:#"favorite_star.png"] forState:UIControlStateNormal];
cell.favBtn.tag = indexPath.row;
[cell.favBtn addTarget:self action:#selector(unfavoriteBtn:) forControlEvents:UIControlEventTouchUpInside];
As mentioned in the comments, you should create the button with a UIButtonTypeCustom type in case it's currently set to UIButtonTypeSystem and you want to avoid the tint color from taking over. Alternatively, you can set the image rendering mode to make sure you always get the original image and not a tinted one:
[[UIImage imageNamed:#"favorite_star.png"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal]

Disabled buttons not changing image in

I have a button that pushes to a settings viewController. On that settings viewController I has a switch to invert all the colors on the original view, an inversion which I've done programmatically. I made inverted button images to replace the original images.
When I return to the original view, I have viewWillAppear call the method to invert if the switch has been flipped. Everything changes accordingly except for two disabled buttons.
The switch value is saved under the default settings so that the user can exit the app and come back later and still have the colors inverted. When viewDidLoad calls the invert method, the buttons change just fine, and they even show up adjusted to show they are disabled.
Any idea what might be going on?
-(void)invert{
self.view.backgroundColor = [UIColor blackColor];
//Buttons
[self.stopButton setImage:[UIImage imageNamed:#"stopinverted"]
forState:UIControlStateNormal];
[self.playButton setImage:[UIImage imageNamed:#"playinverted"]
forState:UIControlStateNormal];
}
-(void)viewWillAppear:(BOOL)animated{
_inverted =
[[NSUserDefaults standardUserDefaults] boolForKey:#"isInvertedOn"];
[[NSUserDefaults standardUserDefaults] synchronize];
if(_inverted){
[self invert];
} else {
[self unInvert];
}
[super viewWillAppear:(BOOL)animated];
}
The issue seems to be that the image is not updated automatically, you'll need to reset the enabled value to make it work:
[self.stopButton setImage:[UIImage imageNamed:#"stopinverted"]
forState:UIControlStateNormal];
self.stopButton.enabled = ! self.stopButton.enabled;
self.stopButton.enabled = ! self.stopButton.enabled;
[self.playButton setImage:[UIImage imageNamed:#"playinverted"]
forState:UIControlStateNormal];
self.playButton.enabled = ! self.playButton.enabled;
self.playButton.enabled = ! self.playButton.enabled;
I think you are disabling stopButton and playButton before applying the image. And also you are applying UIImage for UIButton normal UIControlState. I would suggest do the following code changes
Change this
//Buttons
[self.stopButton setImage:[UIImage imageNamed:#"stopinverted"]
forState:UIControlStateNormal];
[self.playButton setImage:[UIImage imageNamed:#"playinverted"]
forState:UIControlStateNormal];
to
//Buttons
[self.stopButton setImage:[UIImage imageNamed:#"stopinverted"]
forState:UIControlStateDisabled];
[self.playButton setImage:[UIImage imageNamed:#"playinverted"]
forState:UIControlStateDisabled];
In short you have to set UIButton UIImages in disabled state.
For more reference have a look this questions answer Xcode: set image on button only for default state, not also selected
If you set the UIImages according to the state of the UIButton then in the function in which you want to invert the UIImage, you have to only need to handle the state of the UIButton and it will automatically change the image.
Thanks for the help. Here is the answer I came up with, inspired by A-Live's answer.
First I had to set the button as enabled, then set the image, and then disable the button again all within the same method. This has fixed my problem.
[self.playButton setEnabled:YES];
[self.playButton setImage:[UIImage imageNamed:#"playinverted"]forState:UIControlStateNormal];
[self.playButton setEnabled:NO];
try using :
theButton.adjustsImageWhenDisabled = false
this will use your custom image instead of the default dimming.

iOS: I set my uibuttons with tags. How do I change the specific button image based on its tag?

I have a multiple array of buttons called button. Each one is tagged. How do I change the image on the button based on its tag and tag only. As of right now, it only changes the very last button.
-(void)buttonTapped:(id)sender{
NSLog (#"%i",[sender tag])];
[button setImage:[UIImage imageNamed:#"button_change.png"] forState:UIControlStateNormal];
}
Either:
for (UIButton *btn in button) {
if(btn.tag == 1)
{
// do something
break; // don't need to run the rest of the loop
}
}
if you want to use the array (it shouldn't be called 'button', use something with a plural for an array)
or an easier way:
UIButton *btn = (UIButton *)[self.view viewWithTag:1];
However a much simpler way would be to use the param in the callback (unless thats not the button you want). Like so:
-(void)buttonTapped:(id)sender
{
UIButton *tappedBtn = (UIButton *)sender;
[tappedBtn setImage:[UIImage imageNamed:#"button_change.png"] forState:UIControlStateNormal];
}
If you just want to change the button that was tapped the following should work.
-(void)buttonTapped:(id)sender
{
NSLog (#"%i",[sender tag])];
UIButton *tappedButton = (UIButton *)sender;
[tappedButton setImage:[UIImage imageNamed:#"button_change.png"] forState:UIControlStateNormal];
}
If you want to change other buttons then you can retrieve the buttons using
[self.view viewWithTag:1000]; //1000 is the tag you assigned
You don't really need to use tags in the this case. When an IBAction is invoked, the sender parameter is a pointer to the control that triggered the IBAction. (Your button.)
Thus, you already have a pointer to the button.
So, as others have pointed out, your code could read like this:
-(void)buttonTapped:(UIButton *)sender
{
[sender setImage:[UIImage imageNamed:#"button_change.png"] forState:UIControlStateNormal];
}
Note that I changed the type of sender to UIButton so that you don't have to cast it. As long as the action is only ever connected to a button, this is safe to do and makes the code cleaner.
As the other poster pointed out, having an array of buttons called "button" is bad. I renamed it to "buttons" in the code below:
If you wanted to do it using tags and an array of buttons, you could use code like this:
-(void)buttonTapped:(UIButton *)sender
{
NSUInteger tag = [sender tag];
UIButton *aButton = buttons[tag];
[aButton setImage:[UIImage imageNamed:#"button_change.png"] forState:UIControlStateNormal];
}
Create images with names button_change1.png, button_change2.png, etc.
And:
-(void) buttonTapped:(UIButton*)sender
{
NSString* imageName = [NSString stringWithFormat: #"button_change%ld.png", (long)sender.tag];
[button setImage:[UIImage imageNamed:imageName] forState:UIControlStateNormal];
}

Force button to look pressed?

I have a UIButton, and I need to programmatically make it looked like how it looks when my finger is on it (darker).
Is there a way to do this?
Thanks
yourButton.selected = YES;
yourButton.highlighted = YES;
I think you just need to set the "highlight" property to "YES":
button.highlighted = YES;
Or you can set a selected image for the button's normal state:
[button setImage:selectedImage forState:UIControlStateNormal];
I have an easier way. Just use "performSelector" with 0 delay to perform [button setHighlighted:YES] . This will perform re-highlighting after the current runloop ends.
- (IBAction)buttonSelected:(UIButton*)sender {
NSLog(#"selected %#",sender.titleLabel.text);
[self performSelector:#selector(doHighlight:) withObject:sender afterDelay:0];
}
- (void)doHighlight:(UIButton*)b {
[b setHighlighted:YES];
}
One more option, if you want to set a different image for button selection, then set image for UIControlStateSelected and assign selected property to true programmatically.
For eg:
[button setImage:imageOfClicked forState:UIControlStateSelected];
[button setSelected:YES];

UIStepper, change plus and minus images [duplicate]

UIStepper is very convenient but I want to change the appearance of it, I need to have customized icon not the plus and minus and also I want to change the color of the control. How can I achieve this? Thanks in advance!
As of iOS 6.0 you can use - (UIImage *)decrementImageForState:(UIControlState)state and - (UIImage *)incrementImageForState:(UIControlState)state to change the labels on the UIStepper control.
This works for iOS 6.0:
[_stepper setDecrementImage:[UIImage imageNamed:#"decrementIcon.png"] forState:UIControlStateNormal];
This works:
[[UIButton appearanceWhenContainedIn:[UIStepper class], nil] setBackgroundImage:[UIImage imageNamed:#"normal.png"] forState:UIControlStateNormal];
[[UIButton appearanceWhenContainedIn:[UIStepper class], nil] setBackgroundImage:[UIImage imageNamed:#"highlighted.png"] forState:UIControlStateHighlighted];
[[UIButton appearanceWhenContainedIn:[UIStepper class], nil] setBackgroundImage:[UIImage imageNamed:#"disabled.png"] forState:UIControlStateDisabled];
Not sure how future proof it is though.
You cannot presently do this. You'll have to write a custom UIControl object if you want to customize the icons.
From the UIStepper Class Reference, the only parameters you can change are
continuous property
autorepeat property
wraps property
minimumValue property
maximumValue property
stepValue property
value property
You cannot customize the icons.
However, since it is a subclass of UIView, you can try changing the backgroundColor.
Here is solution that works for me.
Platform iOS 7.1
[stepper setBackgroundImage:[UIImage new] forState:UIControlStateNormal];
[stepper setDividerImage:[UIImage new] forLeftSegmentState:UIControlStateNormal rightSegmentState:UIControlStateNormal];
The result is only increment, decrement images are visible.
Here's the Swift 4.0 version:
stepper.setDecrementImage(UIImage(named: "yourDecrementImage.png"), for: UIControlState.normal)
stepper.setIncrementImage(UIImage(named: "yourIncrementImage.png"), for: UIControlState.normal)
I also found that shrinking custom images to fit into the stepper buttons would blur them. This is the only extension function I found that properly shrunk the images down without blurring:
extension UIImage {
func resize(targetSize: CGSize) -> UIImage {
return UIGraphicsImageRenderer(size:targetSize).image { _ in
self.draw(in: CGRect(origin: .zero, size: targetSize))
}
}
}
You can always step through the UIViews and guess, too. Anyway, this is my code, which doesn't answer the question directly, but is kind of neat.
#implementation UIStepper (Util)
- (void) fixForIos7 {
if (!IS_IOS7)
return;
for (UIView *view in self.subviews) {
view.backgroundColor = [UIColor whiteColor];
UIButton *button = (UIButton*)view;
[button setTintColor:[UIColor blackColor]];
}
}
#end
This gist I wrote shows creating a StepperControl as a subclass and set custom style of plus/minus.
P.S I have added a label image in the middle as the divider image.
func image(fromView view: UIView) -> UIImage
In regard your question, you can remove the logic for the label and instead just set blank UIImage() for the divider image.
StepperControl.swift

Resources