UIButton not Blinking on Touch - ios

I have a UIButton, created programmatically, inside a UIView (no other levels to the hierarchy). The button does respond to the touchUpInside event properly, but, for some reason, the text isn't exhibiting its normal "blink" behavior when touched. I'd like to get that back, if anyone knows what could cause this.
Other notes: I have userInteractionEnabled = TRUE and there are no custom animations in my code. Relevant instantiation code (UIColor names are from a custom category):
self.loginButton = [[UIButton alloc] init];
self.loginButton.backgroundColor = [UIColor MPBlackColor];
[self.loginButton setTitle:#"LOG IN" forState:UIControlStateNormal];
[self.loginButton setTitleColor:[UIColor MPGreenColor] forState:UIControlStateNormal];
self.loginButton.titleLabel.font = [UIFont fontWithName:#"Oswald-Bold" size:24.0f];

The problem is that your custom color for the normal state applies also for the highlighted state, unless you give it a separate color for the highlighted state. This is true of all button state related values.

Apply a color for both normal and highlighted button state. In Swift:
loginButton.setTitleColor(.green, for: .normal)
loginButton.setTitleColor(.green, for: .highlighted)
Note: the same logic applies to a blinking button with an image. You should set both .normal and .highlighted states

Related

Unable to change UIButton image inside UITableViewCell

I have a custom UITableViewCell created in a xib and have assigned it a class file of it's own. I have assigned a background image to a UIButton inside this custom cell in IB. In my ViewController where I have a UITableView that uses this cell, I have the below code.
_yesNoCell = (YesNoCell *)[tableView dequeueReusableCellWithIdentifier:#"YesNoCell"];
// Below code is not working
[_yesNoCell.btnYes setImage:[UIImage imageNamed:#"action_selected"] forState: UIControlStateHighlighted];
[_yesNoCell.btnYes addTarget:self action:#selector(btnYesTap:) forControlEvents:UIControlEventTouchUpInside];
Everything works fine, and the btnYesTap method gets called as expected. The background image set in IB shows up, however, what I want is to set a different image when the button is pressed down (not released) i.e the UIControlStateHighlighted. The code above is not working.
I even tried add an action to the button as :
[_yesNoCell.btnYes addTarget:self action:#selector(changeImage:) forControlEvents:UIControlEventTouchDown];
And change the image in changeImage method, but it didn't work.
I referred to similar posts on SO, but none of them seem to have a solution. Referred links : One Two Three
Any help is greatly appreciated.
Actually you setting the button image at Highlighted state but your button is at normal (default) state. So change your button state as like below.
Swift 4
let myImg = UIImage(named: "your-img-name") // your image
myButton.setImage(myImg, for: .highlighted) // set button image for state
myButton.isHighlighted = true // change button state
Objective-C
UIImage *myImg = [UIImage imageNamed:#"your-img-name"];
[myButton setImage:myImg forState:UIControlStateHighlighted];
[myButton setHighlighted:true];
You can do it like that using UIControlStateSelected | UIControlStateHighlighted
[_yesNoCell.btnYes setImage:[UIImage imageNamed:#"action_selected"] forState:UIControlStateSelected | UIControlStateHighlighted];

UIBarButtonItem is disabled, but has normal color

I'm having an issue with a UIBarButtonItem. I use the appearance proxy to set its color for states Normal and Disabled and I do this in the viewDidLoad method of the UIViewController. However, the button gets the Normal color, even when it is disabled (and it is definitely disabled because the IBAction method is not being called).
The question is similar to this one text color of disabled uibarbuttonitem is always the color of the normal state, however, the solution posted here does not work for me.
My app is for iOS 8.2 and I'm using Xcode 6.2
Any ideas?
EDIT:
I am not sure if this is helpful for finding the solution, but when I create my button using initWithImage: instead of initWithTitle: everything seems to be working well. Could this be an Apple bug?
Swift 4
If someone looking for how to change barbuttonitem disabled state appearance in swift. Here you go.
barButtonItem.setTitleTextAttributes([NSAttributedString.Key.foregroundColor: UIColor.lightGray], for: .disabled)
Check with following code.
- (void)viewDidLoad {
[super viewDidLoad];
UIBarButtonItem * btnTemp = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:#selector(btnDone_Click:)];
[btnTemp setTitleTextAttributes:#{NSForegroundColorAttributeName : [UIColor lightGrayColor], NSFontAttributeName:[UIFont boldSystemFontOfSize:16.0f]} forState:UIControlStateNormal];
[btnTemp setTitleTextAttributes:#{NSForegroundColorAttributeName : [UIColor blueColor], NSFontAttributeName:[UIFont systemFontOfSize:16.0f]} forState:UIControlStateDisabled];
[self.navigationItem setRightBarButtonItem:btnTemp];
}
- (void)btnDone_Click : (id)sender {
UIBarButtonItem * button = (UIBarButtonItem *)sender;
[button setEnabled:FALSE];
[self performSelector:#selector(enableButton:) withObject:sender afterDelay:2.0f];
}
- (void)enableButton : (id)sender {
UIBarButtonItem * button = (UIBarButtonItem *)sender;
[button setEnabled:TRUE];
}
So I finally managed to get this working as it should, and the problem was that I was setting the color of UIBarButtonItems twice, once using [navBar setTintColor:] and once using the appearance proxy. Leaving just the appearance proxy solves the problem.
You have likely set the bar button item title text attributes for the .Normal state and need to also set it for the .Disabled state.
There are two ways to fix this, one if you are setting the title text attributes on the bar button item instance and in the other case if you use the appearance proxy.
Single instance:
saveButton.setTitleTextAttributes([NSForegroundColorAttributeName: UIColor.grayColor()], forState: .Disabled)
Appearance proxy:
UIBarButtonItem.appearanceWhenContainedInInstancesOfClasses([MyNavigationController.self]).setTitleTextAttributes([NSForegroundColorAttributeName: UIColor.grayColor()], forState: .Disabled)
This updates the answer for Swift 4.0:
barButtonItem.setTitleTextAttributes([NSAttributedStringKey.foregroundColor: UIColor.gray], for: UIControlState.disabled)
This shows an illustrative example of an orange color for disabled against a white barTintColor:
barTintColor = .white
cancelButton.isEnabled = false
cancelButton.setTitleTextAttributes(
[NSAttributedStringKey.foregroundColor: UIColor.orange],
for: UIControlState.disabled)
This was also my issue, when running on iOS versions 10.*. Setting the button's foreground color solved the issue for me.
self.saveButton.setTitleTextAttributes([NSForegroundColorAttributeName: UIColor.gray], for: UIControlState.disabled)

UIButton image goes grey on press

I've gone through all the other questions concerning button color changes. Here's the situation, I have a button that when pressed causes a view to slide out. Before press the button's image is white, once pressed goes grey (this is acceptable), but when pressed again to return to original location, the image is still grey. I want it back to white and have tried using UIControlStateNormal, Disabled, etc with no success.
[self.button setImage:[UIImage imageNamed:#"someImage"] forState:UIControlStateNormal];
this has been changed to all UIControl types. currently it is set as:
[self.menu setImage:[UIImage imageNamed:#"menu"] forState:UIControlStateNormal];
[self.menu setImage:[UIImage imageNamed:#"menu"] forState:UIControlStateSelected | UIControlStateHighlighted];
and still no luck. Any suggestions?
You can disable adjusting colours of button's subviews by setting property
myButton.adjustsImageWhenHighlighted = false
you have to set the same image for both states of the button : -
self.button.setImage(ImageName, for: .normal)
self.button.setImage(ImageName, for: .highlighted)
The code you have shown simply declares which image the button will be depending on different states, however you will need to physically change the state of the button too so these images can be used for each state.
What I mean by this, is if you have the button show a different image for when the button is selected, you will need to change the button state to selected. To return the image to the original unselected image, you will need change the state back to unselected. For example, let's say within your viewDidLoad method you have the following code to declare the images for each of the button states:
//Set for normal state
[self.button setImage:[UIImage imageNamed:#"normalImage.png"] forState:UIControlStateNormal];
//Set for selected state
[self.button setImage:[UIImage imageNamed:#"selctedImage.png"] forState:UIControlStateSelected];
Now within your IBAction method you can toggle between the states
-(IBAction*)yourButtonIsPressed:(id)sender{
if (!self.button.selected){ //This is checking button state
//The code will run in here if the button is in a normal, unselected state. This is where you have you method here to slide in view etc
//Now change the button to a selected state
self.button.selected = YES;
}else{
//The code will now run in here if the button is already in a selected state and this is where you place your method to return the view etc
//Now set the button back to an unselected state
self.button.selected = NO;
}
}
I hope this helps
It was something completely overlooked. I had the view opacity set. so:
self.layer.opacity = .60;
was the issue. Once I commented that line out, the button works like a charm. Thanks for the help Jim.
If you created the button programmatically make sure to set the type and change the image render mode to use original to maintain the image color.
let image = UIImage(named: "someImage").withRenderingMode(.alwaysOrigianl)
let button = UIButton(type: .system)

Setting the font of titleLabel of UIButton changes the textColor to default one?

I am now developing the application for ios 6 . It is a kind of form designing application where I found that if we change the titlelabel.textColor some point in the application then if we change the font then the textColor changes to the default one at the allocation time.
I checked this like below
I drag a sample button to my sample viewcontroller and create an IBOutlet property named myButton in viewcontroller.h file
in -viewDidLoad
[myButton.titleLabel setTextColor:[UIColor redColor]];
and in button action I did like below
- (IBAction)btnLoginClicke:(UIButton *)sender {
[myButton.titleLabel setFont:[UIFont fontWithName:#"Arial" size:18]];
below are my before and after button click action screenshots
If you are going to keep all the buttons in your application with similar color, then better go for the global appearance settings. Then you need not have to worry about the button title color at all the places.
Put these lines in your appDelegate in the didFinishLaunchWithOptions method.
[[UIButton appearance] setTitleColor:[UIColor redColor] forState:UIControlStateNormal];
[[UIButton appearance] setTitleColor:[UIColor greenColor] forState:UIControlStateHighlighted];
Hope that helps.
If you set the color of your UIButton title using:
[myButton setTitleColor:[UIColor redColor] forState:UIControlStateNormal];
the color information won't be lost when you assign a new font.
I assume this is because the UIButton class internally setup the colour of the textLabel based on the different colours you had setup using setTitleColor (or the storyboard) for the different UIButton states. Changing directly the colour of the textLabel won't change the colour the UIButton has stored for each of these states, and they will be reapplied every time the UIButton needs to redraw itself. This is what happens when you setup the new font - the UIButton has to redraw itself but it will do it using the color setup via setTitleColor:forState:.

Clear button on UITextView

How can I add a clear button (cross inside a circle) for UITextView like UITextField has?
Based on the answer from GhostRider a more accurate and up to date implementation:
int kClearButtonWidth = 15;
int kClearButtonHeight = kClearButtonWidth;
//add the clear button
self.clearButton = [UIButton buttonWithType:UIButtonTypeCustom];
[self.clearButton setImage:[UIImage imageNamed:#"UITextFieldClearButton.png"] forState:UIControlStateNormal];
[self.clearButton setImage:[UIImage imageNamed:#"UITextFieldClearButtonPressed.png"] forState:UIControlStateHighlighted];
self.clearButton.frame = CGRectMake(0, 0, kClearButtonWidth, kClearButtonHeight);
self.clearButton.center = CGPointMake(self.textView.frame.size.width - kClearButtonWidth , kClearButtonHeight);
[self.clearButton addTarget:self action:#selector(clearTextView:) forControlEvents:UIControlEventTouchUpInside];
[self.textView addSubview:self.clearButton];
And the method
- (void)clearTextView:(id)sender{
self.textView.text = #"";
}
You can use this images for the two states of the button:
just make a uibutton and put it on uitextview and set its action for clear text view;
uitextview.frame = (0,0,320,416);
uibutton.frame = (310,0,10,10);
[uibutton setimage:#"cross.png" forcontrolstate:uicontrolstatenoraml];
[uibutton addTarget:self action:#selector(clearButtonSelected:) forControlEvents:UIControlEventTouchUpInside];
-(void)clearButtonSelected{
uitextview=#"";
}
hope you want to clear the text view text when you click on cross button above is help
if not understand then i can send you proper program for that
From product perspective, if you're going to have a clear button, you probably want to use a UITextField instead of a UITextView and UITextField supports a clear button natively - set the clearButtonMode property as such:
UITextField *textfield = ...;
textfield.clearButtonMode = UITextFieldViewModeAlways;
See screenshot:
You could use UITextFieldViewModeWhileEditing to only present the clear button while the user is actively updating the content.
There's nothing built in like there is for the UITextField. You'd have to add the view yourself (probably a UIButton) and place it correctly and also somehow get the text to wrap around it correctly. (And I don't think the latter is really possible.)
Maybe instead you should display a toolbar above the keyboard (or an inputAccessoryView if you're targeting 3.2 and later) that provides a clear button.
For me changing the .frame or the .contentInset properties did not work.
For me the best result came from:
1) adding a UIView to the controller, give it round corners and a border to mimic a UITextView.
self.viewTextBackground.layer.borderColor = [UIColor colorWithRed:171/255.0 green:171/255.0 blue:171/255.0 alpha:1.0].CGColor;
self.viewTextBackground.layer.borderWidth = 1.0f;
self.viewTextBackground.layer.cornerRadius = 9.0f;
2) place UITextView on top of this UIView. Place it so that the borders of the underlying UIView stay visible.
3) give the UITextView round corners:
self.textNote.layer.cornerRadius = 9.0f;
3) Make its width fe. 30pixels less compared to the underlying UIView. You now have space for a clear-button.
4) simply add a UIButton to your controller and place it in the top-right corner of the underlying UIView.
5) change the buttons properties: set its type to 'custom' and set its image to the image of a grey cross.
6) bind an action to the button te clear the UITextView
You can add a clear button like the one in the attached screenshot with minimal coding. Just follow these steps:
Select the storyboard and drag a UIButton into your UITextView
Set the buttons constraints
Assign a title or a background image
Create the button's IBOutlet reference and the action (see onClearPressed(_:) below) for "Touch Up Inside" in the ViewController
Implement the textViewDidChange(_:) UITextViewDelegate delegate method, and make sure to set the button's isEnabled property based on the textfield content, e.g.:
func textViewDidChange(_ textView: UITextView) {
clearButton.isEnabled = !textView.text.isEmpty
}
Implement the onClearPressed(_:) action:
#IBAction func onClearPressed(_ sender: Any) {
textView.text = ""
clearButton.isEnabled = false
}
That's it.

Resources