Unselected button looks like this:
Selected button looks like this:
Why are there two shades of blue? How do I get rid of that paler shade of blue on the inside? I want the entire button to be a single solid color.
I've looked at .backgroundColor, thought maybe there was a .foregroundColor, but I can't find what is doing it...
Here is what I'm using:
func buttonArrayUpdated(buttonSelected: UIButton) {
for b in buttonsArray {
if b == buttonSelected {
selectedButton = b
b.isSelected = true
// default colors for state
b.backgroundColor = .blue
b.setTitleColor(.white, for: .selected)
}
else {
b.isSelected = false
// default colors for state
b.backgroundColor = .white
b.setTitleColor(.blue, for: .normal)
}
}
}
You can do as follows to remove that background color:
button.tintColor = .clear
Related
In my app, I have a button with a text title next to a button that's an image. I want the color scheme of both buttons to match. I create the button with the image like this:
let button1 = UIButton()
button1.setImage(
UIImage(named: "button1")?.withRenderingMode(.alwaysTemplate), for: .normal)
button1.tintColor = UIColor.green
This creates the effect that I want on both buttons, i.e. the button is green, then when it's highlighted it gets tinted to a darker, black-ish green. I tried creating the text button the same way:
let button2 = UIButton()
button2.setTitle("button2", for: .normal)
button2.tintColor = UIColor.green
But, in this case, setting the tint color doesn't change the color of the button's title/text (it remains white even when highlighted). My solution to this is as follows:
let button2 = UIButton()
button2.setTitle("button2", for: .normal)
button2.setTitleColor(UIColor.green, for: .normal)
button2.setTitleColor(UIColor(red: 0x23 / 255.0,
green: 0x34 / 255.0,
blue: 0x16 / 255.0,
alpha: 1.0), for: .highlighted)
Essentially, I've estimated the color that the image gets tinted to when it's highligted and set the text color to match. This works fine, but it bothers me that I only have an approximation; ideally, I would want the system to tint the text color for me when the button is highlighted in the same way that it tints the image. I get that this is a really small problem and that fixing it probably won't noticeably improve the app, but I'd still like to know if there's a way to tint a button with a text title "automatically" (as opposed to hardcoding the tint).
Tint color is property of UIView, which doesn't have a state. State is property of UIControl(Button's parent class). Means that you cannot change the tint on the bases of button's state. You can only change properties mentioned seen in this screen shot on the basis of button's state by default.
Also the
darker, black-ish green
color your getting that the default behaviour of button to change background color to show highlighted state
Solution : CustomButton
Create a custom UIButton
class MyButton : UIButton {
override var isHighlighted: Bool{
didSet {
tintColor = isHighlighted ? UIColor.green : UIColor.red
// do additional work here according to your need
}
}
override var isSelected: Bool {
didSet {
// do changes according to you need
}
}
}
You can also set the properties mentioned in above image programmatically.
button.setTitleColor(UIColor.green, for: .normal)
button.setTitleColor(UIColor.red, for: .highlighted)
button.setBackgroundImage(yourBackgroundImage, for: .normal)
let button2 = UIButton()
button2.addTarget(self, action: #selector(self.pressed), for: [.touchDown])
button2.addTarget(self, action: #selector(self.released), for: [.touchDragExit, .touchUpInside, .touchUpOutside, .touchCancel])
func pressed() {
// set colour
}
func released() {
// set colour
}
I am trying to change the image on my button depending on the position of a switch. I am not sure how to do this. I am relatively new to code. I have managed to change the other things on the screen but not the button. I have attached my code. I put this function into the IBAction for the switch:
func updateMySwitchState(){
if darkModeSwitch.isOn {
self.view.backgroundColor = UIColor.black
removeAds.textColor = UIColor.white
aboutText.textColor = UIColor.white
about.textColor = UIColor.white
backButton.setImage(UIImage(named: "backinvert-40"), for: .normal)
} else {
self.view.backgroundColor = UIColor.white
removeAds.textColor = UIColor.black
aboutText.textColor = UIColor.black
about.textColor = UIColor.black
backButton.setImage(UIImage(named: "back-40"), for: .normal)
}
}
Did you connected the outlet of the button with the controller?
You can set both images button image in storyboard itself for normal & selected state respectively. After setting call
backButton.setSelected(true) for first image and
backButton.setSelected(false) for the second
I recently asked a question here where I wanted to understand how to change the UIColor of a button's image. I followed #Dorian Roy's recommendation which was very clean and it worked well for my needs. While my specific question previously was around a single button, I would like to know how to change multiple UIBUttons. Can this be done? My thought would be to subclass a UIButton and initialize it to automatically change its image color. I can't quite grasp how to do this though.
Here is how I am currently performing this action and I am seeking a more elegant solution.
private func changeBtnColors() {
let ccStencil = creditCardBtn.imageView?.image?.withRenderingMode(.alwaysTemplate)
let planeStencil = planeBtn.imageView?.image?.withRenderingMode(.alwaysTemplate)
let towelStencil = towelBtn.imageView?.image?.withRenderingMode(.alwaysTemplate)
let carStencil = carBtn.imageView?.image?.withRenderingMode(.alwaysTemplate)
let trainStencil = trainBtn.imageView?.image?.withRenderingMode(.alwaysTemplate)
let graphStencil = graphBtn.imageView?.image?.withRenderingMode(.alwaysTemplate)
creditCardBtn.setImage(ccStencil, for: .normal)
planeBtn.setImage(planeStencil, for: .normal)
towelBtn.setImage(towelStencil, for: .normal)
carBtn.setImage(carStencil, for: .normal)
trainBtn.setImage(trainStencil, for: .normal)
graphBtn.setImage(graphStencil, for: .normal)
creditCardBtn.tintColor = UIColor.white
planeBtn.tintColor = UIColor.white
towelBtn.tintColor = UIColor.white
carBtn.tintColor = UIColor.white
trainBtn.tintColor = UIColor.white
graphBtn.tintColor = UIColor.white
}
The simplest way is create one array of UIButton and loop through all the elements.
let buttonArray = [creditCardBtn, planeBtn, towelBtn, carBtn, trainBtn, graphBtn]
buttonArray.forEach { button in
let image = button.imageView?.image?.withRenderingMode(.alwaysTemplate)
button.setImage(image, for: .normal)
button.tintColor = UIColor.white
}
You can also create extension of UIButton and put this settings code of Button in a function like this.
extension UIButton {
func setImageWithRandringMode() {
let image = self.imageView?.image?.withRenderingMode(.alwaysTemplate)
self.setImage(image, for: .normal)
self.tintColor = .white
}
}
And now simply call this function with forEach closure.
buttonArray.forEach { button in
button.setImageWithRandringMode()
}
I have a maddening problem. I have a rating control with 4 buttons.
They are each initialised like this in a loop:
var button: UIButton? = nil;
//..
button = UIButton(type: UIButtonType.System);
//..
imageDefault.imageWithRenderingMode(UIImageRenderingMode.AlwaysTemplate);
mageHighlight.imageWithRenderingMode(UIImageRenderingMode.AlwaysTemplate);
imageProgress.imageWithRenderingMode(UIImageRenderingMode.AlwaysTemplate);
//..
button!.setImage(imageDefault.Content!, forState: .Normal)
button!.setImage(imageHighlight.Content!, forState: .Highlighted)
button!.setImage(imageProgress.Content!, forState: .Selected)
The fun starts when one of the buttons it clicked. If e.g. 2nd is clicked the two first should be the same color while the rest look like standard. With 3 buttons, same concept, but another color.
When a click happens I have code like this:
func updateButtonSelectionStates() {
let idx: Int = self.tag;
var rating: Int = 3; // whatever
for (index, button) in ratingButtons.enumerate() {
button.selected = (index+1) <= Int(rating);
var color: UIColor = UIColor.blackColor();
if (index+1) <= Int(rating) {
switch (rating % 4) {
case 0: color = UIColor.blueColor();
case 3: color = UIColor.greenColor();
case 2: color = UIColor.yellowColor();
case 1: color = UIColor.redColor();
default: msNoOp();
}
}
if (button.imageView != nil) {
button.imageView!.tintColor = color;
}
}
Problem is - any button set to "Selected" disappears - no graphic is shown.
It works for most buttons if I explicitly set "selected" = false, but.... This solution does not NOT work for the actual button clicked. It still appears hidden / graphic invisible.
Whatever solution appears, it should also run on iOS7 ...
I have a scrollview inside a view. Inside the scrollview I create programmatically 5 buttons. Every button loads a different image with a different tag each one. I added a function that is called when pressing the buttons.
let avatarsListScrollingView = avatarsListView(CGSizeMake(70.0, 55.0), avatarCount: 5)
func avatarsListView(buttonSize:CGSize, avatarCount:Int) -> UIView {
**CODE**
for i in 0...(avatarCount-1) {
let button = UIButton(type: .Custom)
**CODE**
button.setImage(UIImage(named: avatarsList[i]), forState: .Normal)
button.tag = i
button.addTarget(self, action: "avatarListSelected:", forControlEvents: .TouchUpInside)
avatarButtonView.addSubview(button)
}
return avatarButtonView
}
Then when pressing the buttons, I call to "avatarListSelected":
func avatarListSelected(sender:UIButton){
if let image = sender.imageView?.image?.imageWithRenderingMode(.AlwaysTemplate) {
sender.setImage(image, forState: .Normal)
sender.tintColor = UIColor.redColor()
}
self.addAvatarView.reloadInputViews()
}
This function tints the image button to red, it is working fine, but the problem is that when I press some other button, I want the other one goes to the original color. Right now every button that I press gets in red.
I tried to add the call to "self.addAvatarView.reloadInputViews()" to try to "redraw" again all the buttons, but never gets called.
Do you guys know some way to do this?
Thanks to everybody!
This is the final code that solved the problem:
func avatarListSelected(sender:UIButton){
print(sender.tag)
if let image = sender.imageView?.image?.imageWithRenderingMode(.AlwaysTemplate) {
sender.setImage(image, forState: .Normal)
sender.tintColor = UIColor.redColor()
}
for view in self.avatarButtonView.subviews as [UIView] {
if let btn = view as? UIButton {
if btn.tag != sender.tag {
btn.setImage(UIImage(named: avatarsList[btn.tag]), forState: .Normal)
}
}
}
}
Create a property selectedButton: UIButton? and keep a reference to the selected button there. Don't forget to update it in avatarListSelected method and before you change it, if it isn't nil, change its color to original (and then change it).
If the buttons have different original colors, subclass UIButton class and keep the original color there.
I don't know if is better approach or answer, but, i maybe could delivery this using this approach:
Create a method that will "fill" the color for your choice button and "clear" color to others , but its a method that loop through UIScrollView and look for each UIButton. Something like this :
func setBackgroundColorButton(color:UIColor , buttonTag:Int){
for view in self.scrollView.subviews as [UIView] {
if let btn = view as? UIButton {
if btn == buttonTag {
btn.tintColor = color
} else {
btn.tintColor = UIColor.whiteColor()
}
}
}
}
This is the concept, i didn't tested, but maybe just need adjust to search inside your scroll view or similar.
But with this will be work nice i believe :D
You could do it like this
for i in 0...5 {
let button = UIButton(type: .Custom)
let x = 50 * i + 10
let y = 50
button.frame = CGRectMake(CGFloat(x), CGFloat(y), 40, 40)
button.setTitle("\(i)", forState: .Normal)
button.tag = i
button.backgroundColor = UIColor.greenColor()
button.tintColor = UIColor.blueColor()
button.addTarget(self, action: "avatarListSelected:", forControlEvents: .TouchUpInside)
self.view.addSubview(button)
}
func avatarListSelected(sender : UIButton){
sender.backgroundColor = UIColor.orangeColor()
for view in self.view.subviews{
if(view.isKindOfClass(UIButton)){
let button = view as! UIButton
if button.tag != sender.tag{
button.backgroundColor = UIColor.greenColor()
}
}
}
}
The frame etc is just for demonstation purpose only, you should of course use your own value. The tintColor property is not valid for all button types. Read the documentation for more information.