Changing color of button text and state - swift

I need to change the color of my button's text.
I also need to change the state to Disabled after the user presses it.
I have no idea how to do this. I've been looking things up for a while but they're all either in objective C or I can't understand it (usually help docs, they're stupid.).

In swift you change color for a specific State with the setTitleColor method.
In you case it will be :
button.setTitleColor(UIColor.grayColor, forState: UIControlState.Normal)
Swift 5 Update:
button.setTitleColor(UIColor.grayColor, for: UIControl.State.normal)

To change color of text
button.titleLabel.textColor = UIColor.grayColor()
To change state, on button press add following -
button.enabled = true
IBAction method should be like -
#IBAction func buttonTapped(sender : UIButton!) {
sender.enabled = false
}

Swift 3
button.setTitleColor(UIColor.gray, for: UIControlState.normal)
Note that;
grayColor has been renamed to gray
Normal is now normal (lowercase)
You have to set the text colour for the specific button state.

For Swift3, try below code :
#IBAction func butnClicked(sender : UIButton) {
sender.setTitleColor(.red, for: .normal)
sender.isEnabled = false
}
Set Enabled and text color from story board.

Related

Correct and incorrect answer in Swift

I'm making simple quiz app about countries in Europe, I have a map and three buttons below with names of countries, one of them is correct and of course two incorrect. I want to highlight incorrect (if user click incorrect button) button for red and correct for green, if user click correct button I want to highlight it for green and after maybe 5s come back to the same color that was at first. I know how to change button color but I don't know ho do that for 5s and come back to default color. How can I do that ? Below its code that I use to change button color
UIButtonOutlet.Backgroundcolor.Uicolor.green
But its default green, so I can't set my color.
You can try something like this. First declare one UIButton instance in your class and then scheduledTimer after setting backgroundColor of button for correct's and incorrect and store that button reference with button that you have created first.
var selectedButton = UIButton()
Now use this selectedButton when you are setting button's backgroundcolor.
btnOutlet.backgroundcolor = .green //For correct
btnOutlet.backgroundcolor = .red //For incorrect
self.selectedButton = btnOutlet
//Now scheduled the timer for 5.0 sec
Timer.scheduledTimer(timeInterval: 5.0, target: self, selector: #selector(setButtonBGBack), userInfo: nil, repeats: false)
Add the setButtonBGBack method in your class
func setButtonBGBack() {
self.selectedButton.backgroundcolor = .blue //Set to default here
self.selectedButton = UIButton()
}
Lets say you have your code for changing the color which is in the "changeColor" func:
var correctButton: UIButton
func changeColor() {
if correctButton.backgroundColor == .green {
correctButton.backgroundColor = .lightGray //back to original color
}
}
What this essentially does is changes your correct button color back to its default (whatever that may be) if it is green when the func is called.
Now to use this, we can do a little work inside of the IBAction that is connected to each of your buttons:
#IBAction func buttonClicked(sender: UIButton) {
if sender.titleLabel?.text == "Correct Answer" {
button.backgroundColor = .green
correctButton = button //set the correct button variable so the changeColor func can be used
let timer = Timer.init(timeInterval: 5, target: self, selector: #selector(changeColor), userInfo: nil, repeats: false)
} else if sender.titleLabel?.text == "False Answer 1" || sender.titleLabel?.text == "False Answer 2" {
button.backgroundColor = .red
}
}
So in this code, if you click the button that is the correct answer (you can identify this by tag or other means, but I just decided to use its text) then the color is set to green immediately, and then the correctButton variable is set, but then a timer is initiated that after five seconds will call your changeColor func and then change it back to its original color.
Hope this helps :)
Edit:
Of course, my method assumes that you are using the storyboard to create these buttons. If you are creating them programmatically, then NiravD's method will work better.

How do I make a UIButton have the correct appearance with image and text?

I have a UIButton that has both an image and text in it. I am quite happy with its appearance except for when it is pressed.
Before it is pressed it looks like this:
After it is pressed it looks like this:
I am used to the appearance darkening the entire button when pressed, but for some reason when I have both an image and text is designates all the coloration to the image. I am quite aware that I can just make the entire button an image, but I am trying to keep this project as away from that style as possible. All of my other button are created with no images.
Is there any way to make the entire button darken as it normally would as it is currently setup?
You have to set the UIButton to Custom type (no System type) and change that properties:
self.yourButton.adjustsImageWhenHighlighted = false
If I get what you want try with that code:
override func viewDidLoad() {
super.viewDidLoad()
self.button.backgroundColor = UIColor.redColor()
}
#IBAction func buttonClicked(sender: UIButton) {
//Touch Up Inside action
sender.backgroundColor = UIColor.redColor()
}
#IBAction func buttonReleased(sender: UIButton) {
//Touch Down action
sender.backgroundColor = UIColor.grayColor()
}
Normal:
Pressed:
The simplest solution would be to match the text's highlight color:
button.setTitleColor(UIColor.gray, for: UIControlState.highlighted)

how to change bordercolor when Button.isHighlighted

I wonder how I get my border around my UIButton to change opacity together with the text inside it, when it is either clicked or highlighted.
My logic tells me, that it should be something like this.. but it doesn't seem to work:
//BTN STYLING
btnstd.layer.cornerRadius = 5
btnstd.layer.borderWidth = 1.5
btnstd.layer.borderColor = UIColor.white.cgColor
//Change bordercolor when highlighted
if(btnstd.isHighlighted) {
btnstd.layer.borderColor = UIColor(white:1,alpha:0.3).cgColor
}
This is by the way put inside my ViewDidLoad() function
The actions you are looking for are .touchDown and anything .touchUp:
override func viewDidLoad() {
super.viewDidLoad()
theButton.setTitle("Normal", for: .normal)
theButton.setTitle("Highlighted", for: .highlighted)
theButton.layer.borderColor = UIColor.red.cgColor
theButton.layer.borderWidth = 1
theButton.addTarget(self, action: #selector(startHighlight), for: .touchDown)
theButton.addTarget(self, action: #selector(stopHighlight), for: .touchUpInside)
theButton.addTarget(self, action: #selector(stopHighlight), for: .touchUpOutside)
}
func startHighlight(sender: UIButton) {
theButton.layer.borderColor = UIColor.green.cgColor
theButton.layer.borderWidth = 1
}
func stopHighlight(sender: UIButton) {
theButton.layer.borderColor = UIColor.red.cgColor
theButton.layer.borderWidth = 1
}
It depends on what you are trying to do.
Case #1: You want this change to happen when the button is highlighted, but in a normal state have a different set of properties.
let theButton = UIButton()
// set common properties and layout code
theButton.setTitle("Normal", for: .normal)
theButton.setTitle("Highlighted", for: .highlighted)
In addition, you have setTitleColor(), setAttributedTitle, setTitleShadowColor(), setImage(), and setBackgroundImage() that you can code directly.
Border color in this case would need a subclass (not an extension, you want public properties) where you will check self.layer.hitTest() after wiring up a tap gesture on self.
Case #2: You want the button state to change when clicked, and stay changed.
You are part way there. If you supply the button in IB, make sure you add an IBAction for event touchUpInside. If you are working in code, here's the Swift 3 syntax.
theButton.addTarget(self, action: #selector(changeButton), for: .touchUpInside)
func changeButton(sender: UIButton) {
sender.setTitle("New Title", for: .normal)
sender.layer.borderColor = UIColor.red.cgColor
}
My preference (but only that) is to more strongly-type the sender (I think that's the correct term) for my actions. I'm sure there are pros and cons for using a specific sender (like UIButton) over AnyObject, but in this case I think the biggest reason is you don't need to force-cast the sender to UIButton.

UIButton setTitle doesn't work

I'm trying to change the text of a UIButton when it gets clicked. I've tried the following things, which failed:
First I tried inserting a button on the storyboard and linking it to the view controller, with the code for the button appearing like this:
#IBAction func button(sender: AnyObject) {}.
Within the button's parentheses, I then used
button.setTitle ("something" , for State: .Selected)
However, when I run this code in the simulator, it doesn't seem to work at all.
I have also tried, following the Apple reference manual, to set different labels for different states in the side menu after clicking on said button, but still this didn't work.
Can anyone tell me exactly (i.e. what code to write and where exactly it goes) how to make this happen?
The type of the sender should be UIButton, when creating the IBAction function.
The sender is your button. The function is called when you tap on the button. You must use the function setTitle on the sender(your button).
#IBAction func buttonTouchedUpInside(sender: UIButton) {
sender.setTitle("buttonName", forState: .normal)
}
Swift 4:
Plain Title
The setTitle() method will work for titles that are "Plain" as defined in the button's Attributes inspector.
#IBAction func button(sender: UIButton) {
sender.setTitle("buttonName", for: .normal)
}
Attributed Title
The setTitle() method has no effect on a button's title if it's configured as "Attributed" in the Attributes inspector. To manage this situation, first get the attributed title from the button, then set the value.
#IBAction func button(sender: UIButton) {
let attributedTitle = sender.attributedTitle(for: .normal)
attributedTitle?.setValue("buttonName", forKey: "string")
sender.setAttributedTitle(attributedTitle, for: .normal)
}
In practically, if you use button from Storyboard or Xib file, and not clear button value in (Storyboard, Xib), than setTitle method doesn't work. If you cleared button value, setTitle method is work.
Create an IBOutlet for your button, then this code should work (assuming you named your IBOutlet button):
button.setTitle("title", forState: .Normal)
button.setTitle("title 1", forState: .Application)
button.setTitle("title 2", forState: .Highlighted)
button.setTitle("title 3", forState: .Reserved)
button.setTitle("title 4", forState: .Selected)
button.setTitle("title 5", forState: .Disabled)
place it in your viewDidLoad() method.
This worked for me.
dispatch_async(dispatch_get_main_queue(), ^{
[self.btnAssment setTitle:#"ASSDate" forState:UIControlStateNormal];
});
let button = UIButton()
button.setTitle("Button", for: .normal)
button.setTitleColor(.black, for: .normal)
I just had a similar issue, and none of the answer here worked in my case.
For me the solution was to call button.layoutSubviews() to update UIButton's label just after i changed the title.
(also I had to change the button type to custom, otherwise the title change would blink)

Hide UIButton title

I have several UIButtons in a scrollview which I use in order to pass certain information. The information is saved in the title of each uibutton and when the button is clicked, it passes its title into the function.
All I want to do is hide the title of the button so you can not see the button. I have them overlaid over images which I use to show buttons. I have the text set to transparent but it still turns white when it is being clicked.
If you include code in your explanation, please explain where it should go.
After IOS7, If you want to just hide the title on titleLabel of a button you can do as follow. This way the title is still there it just makes it invisible. if you do NSLog("%#",button.currentTitle) you will see the title in terminal. Hope this helps.
[button setTitle:#"Button Title" forState:UIControlStateNormal];
button.titleLabel.layer.opacity = 0.0f;
I found only one correct working way:
//hide
yourButton.setTitleColor(UIColor.clearColor(), forState: .Normal)
//show (put your color)
yourButton.setTitleColor(UIColor.blackColor(), forState: .Normal)
using button.titleLabel.hidden = YES will not work (at least on on iOS 7).
I ended up using:
// remove the button since hiding it doesn't work
[button.titleLabel removeFromSuperview];
// put back when you're done
[button addSubview:button.titleLabel];
You can hide the label inside the button:
button.titleLabel.hidden=YES;
or set the button's title to #"" and save the value somewhere else when you want to retrieve it.
I create a subclass of UIButton and override layoutSubviews method. Hiding titleLabel in layoutSubviews method works.
public class LoadingButton: UIButton {
public var isTitleHidden: Bool = false {
didSet {
titleLabel?.isHidden = isTitleHidden
}
}
public override func layoutSubviews() {
super.layoutSubviews()
titleLabel?.isHidden = isTitleHidden
}
}
if wanna hide titleLabel, just set isTitleHidden = true
I could not remove the title from the titleLabel nor the whole view as I needed it for constraints.
I ended up using
isEnabled = false
titleLabel?.layer.opacity = 0
setTitleColor(.clear, for: .disabled)
to hide the title and
isEnabled = true
titleLabel?.layer.opacity = 1
setTitleColor(titleColor(for: .normal), for: .disabled)
to show it again
To hide a title temporary just setTitle to empty string
setTitle("", for: .normal)
the button title label will be hidden but the title will still in the titleLabel, you can return it back using
setTitle(titleLabel?.text, for: .normal)
If you want to temporary hide the title, while you disabling the button, use:
setTitle("Title", for: .normal)
setTitle("", for: .disabled)
Then, button.isEnabled = false, when you want to hide the title.
I got a problem with title, because used an attributed title and nothing above helped. Then i found a workaround:
button.titleEdgeInsets = .init(top: 0, left: shouldHide ? 1000 : 0, bottom: 0, right: 0)
However it has some disadvantages, but fit my needs.
I've come up with this solution, which allows you to set title label text and use it with button image without showing it and not moving button image to the left.
- (void)hideButtonLabel:(UIButton*)buttonInp {
buttonInp.titleLabel.layer.opacity = 0.0f;
uttonInp.titleLabel.font = [UIFont fontWithName:#"Helvetica-Light" size:0.0];
}
You cannot hide UIButton titleLabel using .hidden property. Instead you can do this.
To Hide:
[self.yourButton setTitle:nil forState:UIControlStateNormal];
To Show:
[self.yourButton setTitle:#"Your Text" forState:UIControlStateNormal];
In Swift-
You don't need to hide nor need to make the opacity to 0.0. Swift gave you a simpler way.
Just set the title as nil. In fact, I got the idea from the documentation.
Command click on the setTitle(_:for:) method and you will see-
open func setTitle(_ title: String?, for state: UIControl.State) // default is nil. title is assumed to be single line
So, I just set it to nil.
setTitle(nil, for: .normal)
Swift 5 to hide button label:
myButton.titleLabel?.isHidden = true
Here myButton is a #IBOutlet of the button.