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 ...
Related
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
I'm still new with Swift 4 and i found this on the internet & tried to make this Button to show "something" when the image button is A. But when i clicked the Button again, only its image button changed but the "something" still not hidden. Can someone help ?
I already done with other button that using this animation but the button is showing another button from Library.
But this 1 is different, not showing another button from Library but showing ChromaColorPicker
var sizeOff = UIImage(named: "Brush-Size")
var sizeOn = UIImage(named: "Brush-Size-On")
============================ somewhere else ======================
extension ViewController {
#IBAction func BrushColourClicked(_ sender: UIButton) {
if sender.currentImage == ColourOn {
sender.setImage(ColourOff, for: .normal)
} else {
sender.setImage(ColourOn, for: .normal)
} // Image first set
configureUI()
}
func configureUI() {
let colorPicker = ChromaColorPicker(frame: CGRect(x: 25.0, y: 410.0, width: 140.0, height: 140.0)) // Position & Size of Color Picker
ColourButtonCenter = colorPicker.center
colorPicker.center = BrushColour.center
colorPicker.delegate = self
colorPicker.padding = 5.0
colorPicker.stroke = 3.0
colorPicker.hexLabel.isHidden = true
colorPicker.layout()
view.addSubview(colorPicker)
colorPicker.alpha = 0
if BrushColour.currentImage == ColourOn {
UIView.animate(withDuration: 0.35, animations: {
colorPicker.alpha = 1
colorPicker.center = self.ColourButtonCenter
})
} // Animation show
else {
UIView.animate(withDuration: 0.35, animations: {
colorPicker.alpha = 0
colorPicker.center = self.BrushColour.center
})
} // Animation hide
}
}
i dont know if
colorPicker.alpha = 0
is working or not
Every time you call configureUI you're adding a new colour picker to the view, then animating the alpha on it.
So when you're trying to hide the colorPicker what's actually happening is that you're adding a new colour picker with alpha 0 and animating it to alpha 0 (doing nothing), the previous colorPicker will still be visible so it will look as though nothing as changed.
Create a variable for colorPicker once and add it to the view, then configure that instance in your configureUI function.
I have looked through other questions but can't find a definitive answer - I created my UIButton in my storyboard (not programmatically) and I am trying to tint the WHOLE button (not just text) on click. I have set my tint color to black and yet this does not affect the whole button.
I have tried setting my type to System as I heard that affects it but nothing has changed. Still no tint.
Furthermore I have to touch/click very "forcefully" (really press down if on device) to even trigger the tint color affecting the text on the button even though the button click registers.
The button's action func will be called so it does not affect functionality, but the text "highlighted state" seems to be only triggered if the user clicks really hard.
How can I tint the entire button? And why would the highlighted state only be triggered with really forced clicking?
Setting tint color -
Trying to implement with IBOutlet:
#IBOutlet var postBtn: UIButton!
postBtn = customButton()
postBtn.highlightedColor = UIColor.blueColor()
after creating custom class in new file:
public class customButton: UIButton {
public var highlightedColor = UIColor.blueColor()
public var unhighlightedColor = UIColor.clearColor()
override public var highlighted: Bool {
didSet {
if (highlighted) {
self.backgroundColor = UIColor.blueColor()
}
else {
self.backgroundColor = UIColor.clearColor()
}
}
}
}
I either get a bad access error if I declare postBtn initially as a customButton() or I am told postBtn has no member called highlightedColor. What am I doing wrong?
tint property sets the color of the button image and text.
As you don't have any image on your button, it only affect the color of the text
Also, tint will only affect the color of button's image when you set the button type to any except custom.
Now for example, we want to set the color of button image to red.
Then we will see:
In your case, you actually want to set the background color and title color of UIButton when button is highlighted.
For title color, you can directly use button.setTitleColor(UIColor.whiteColor(), forState: .Highlighted)
For background color, there is no direct method you can use, but you can create a custom UIButton which override the highlighted property of UIButton or use setBackgroundImage:forState:
Custom UIButton
public class customButton: UIButton {
public var highlightedColor = UIColor.blueColor()
public var unhighlightedColor = UIColor.clearColor()
override public var highlighted: Bool {
didSet {
if (highlighted) {
self.backgroundColor = UIColor.blueColor()
}
else {
self.backgroundColor = UIColor.clearColor()
}
}
}
}
Usage:
let button1 = customButton()
let button2 = customButton()
button1.highlightedColor = UIColor.redColor()
button2.highlightedColor = UIColor.blueColor()
button1.unhighlightedColor = UIColor.clearColor()
button2.unhighlightedColor = UIColor.blackColor()
setBackgroundImage:forState:
Another method to achieve what you want is use setBackgroundImage:forState:. You may need to create an UIImage from UIColor first.
Generate a image from UIColor:
func getImageWithColor(color: UIColor, size: CGSize) -> UIImage {
let rect = CGRectMake(0, 0, size.width, size.height)
UIGraphicsBeginImageContextWithOptions(size, false, 0)
color.setFill()
UIRectFill(rect)
let image: UIImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return image
}
Usage:
button1.setBackgroundImage(getImageWithColor(UIColor.redColor(), size: button1.bounds.size), forState: .Highlighted)
button2.setBackgroundImage(getImageWithColor(UIColor.blueColor(), size: button2.bounds.size), forState: .Highlighted)
Try like this,
1) Set UIButton type to custom from storyboard
then write like below,
Create IBoutlet for that button like,
#IBOutlet var btnSubmit : UIButton!
Create click event of that button,
#IBAction func btnSubmitClick(sender : UIButton)
{
if(sender.selected == false)
{
self.btnSubmit.backgroundColor = UIColor.redColor()
self.btnSubmit.selected = true
}
else
{
self.btnSubmit.backgroundColor = UIColor.blueColor()
self.btnSubmit.selected = false
}
}
This will change your whole button background color. Hope this will help you :)
With regards your first question, you would need to do this in code. The tint only affects the text. If you wanted the background colour to change, you would need to change it manually as the button state changes. One way to do this would be to subclass UIButton and add a target/action on it for the relevant control events. In your case, you would listen to UIControlEventTouchDownto know when to change the background colour to your chosen 'highlight' colour, and UIControlEventTouchDragExitand UIControlEventTouchUpInside to know when to revert back to the normal state background colour.
Here's an existing implementation if you want to save time: https://github.com/TakeScoop/SwiftyButton
Swift 3
For anyone doing it programatically:
var button = UIButton(type: .system)
button.tintColor = UIColor.blue
I want to be able to check if all buttons' background color is UIColor.whiteColor. I'm determining whether a view is in search mode or in normal mode by the button state.
I want to do something similar with the following but contains() checks if array contains certain value. It wouldn't work in my case because UIColor.whiteColor is a property of UIButton.
if contains(categoryScrollView.subviews, UIColor.whiteColor) {
inSearchMode = false
}
Then if I put it in the following way, I do not know how I can make sure all button's background color is white as it will pass validation as soon as any button's background color is white which is not what I need.
for button in categoryScrollView.subviews {
if button.backgroundColor == UIColor.whiteColor() {
inSearchMode = false
}
}
How can I check is background color of all buttons?
I'd enclose this check in a function, like this (note that I'm including a check that each view is a button):
func allWhiteButtons(view: UIView)-> Bool{
for view in view.subViews {
if let button = view as? UIButton {
if button.backgroundColor != UIColor.whiteColor() {
return false
}
}
}
return true
}
var allWhite = true
for button in categoryScrollView.subviews {
if button.backgroundColor != UIColor.whiteColor() {
allWhite = false
}
}
inSearchMode = !allWhite
But IMHO, this is not a good way to do it at all. You should have a code to do state transition and make the buttons white or not white based on this state.
If you don't have a lot of UIButtons and that they are already declared as IBOutlets you can create a function that loops through all your UIButtons :
for button in [yourButton1, yourButton2, yourButton2] {
if button.backgroundColor == UIColor.whiteColor {
// Do something
} else {
// Do something else
}
}
Or you can also loop through all the buttons of your self.view :
for view in self.view.subviews as [UIView] {
if let button = view as? UIButton {
if button.backgroundColor == UIColor.whiteColor {
// Do something
} else {
// Do something else
}
}
}
Add a counter like whiteBtnCount in the loop where you are checking the backgroundcolor.Increment that counter if it matches the color and break the loop once counter reaches the button count. Voila,now you know whether all buttons are white color or not.
var whiteBtnCount: Int = 0
for button in categoryScrollView.subviews {
if button.backgroundColor == UIColor.whiteColor() {
whiteBtnCount += 1
if whiteBtnCount == btnCount { //ensure btnCount variable holds the number of buttons
inSearchMode = false
break
}
}
}
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.