UIButton background color overlaps text on highlight - swift

After I set my UIButton's backgroundColor and textColor for state highlighted the following output is presented:
The problem here is that the button's background overlaps the white text. How can I solve this?
I also have lots of problem on tvOS with setting the background and text color from the Interface Builder (not working from State Config). I have to make a combination of the IB's properties and code.
Here is my code:
if shopNowButton.highlighted == true {
shopNowButton.highlighted = false
shopNowButton.backgroundColor = UIColor.orangeColor()
shopNowButton.setTitleColor(UIColor.whiteColor(), forState: .Highlighted)
}
else {
shopNowButton.highlighted = true
shopNowButton.backgroundColor = UIColor.whiteColor()
shopNowButton.layer.borderWidth = 1
shopNowButton.layer.borderColor = UIColor.orangeColor().CGColor
shopNowButton.setTitleColor(UIColor.orangeColor(), forState: .Normal)
}

This may help.
Change the Button-Type: System to Custom (IB or programmatically),
Follow image
changes behaviour of highlighted button.
Add this property in your method "adjustsImageWhenHighlighted = NO".

I believe the UIControlState you're actually looking for is Focused rather than Highlighted.
Here's an example of how to change the backgroundColor and titleColor of a UIButton when it becomes focused. (Accomplished with the help of this answer):
import UIKit
class ViewController: UIViewController {
let myButton = UIButton(type: UIButtonType.Custom)
let myOtherButton = UIButton(type: UIButtonType.Custom)
override func viewDidLoad() {
super.viewDidLoad()
// Button we will change on focus
myButton.frame = CGRectMake(view.frame.midX - 300, view.frame.midY, 400, 100)
myButton.setTitle("myButton", forState: .Normal)
// Normal
myButton.backgroundColor = UIColor.whiteColor()
myButton.setTitleColor(UIColor.orangeColor(), forState: .Normal)
// Focused
myButton.setBackgroundImage(imageWithColor(UIColor.orangeColor()), forState: .Focused)
myButton.setTitleColor(UIColor.whiteColor(), forState: .Focused)
view.addSubview(myButton)
// Other button so we can change focus // Just for example
myOtherButton.frame = CGRectMake(view.frame.midX + 300, view.frame.midY, 400, 100)
myOtherButton.setTitle("myOtherButton", forState: .Normal)
// Normal
myOtherButton.backgroundColor = UIColor.whiteColor()
myOtherButton.setTitleColor(UIColor.orangeColor(), forState: .Normal)
// Focused
myOtherButton.setBackgroundImage(imageWithColor(UIColor.orangeColor()), forState: .Focused)
myOtherButton.setTitleColor(UIColor.whiteColor(), forState: .Focused)
view.addSubview(myOtherButton)
}
// Function to create a UIImage filled with a UIColor
func imageWithColor(color: UIColor) -> UIImage {
let rect = CGRectMake(0, 0, 1, 1)
UIGraphicsBeginImageContext(rect.size)
let context = UIGraphicsGetCurrentContext()
CGContextSetFillColorWithColor(context, color.CGColor)
CGContextFillRect(context, rect)
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return image
}
}
This example in action:

Related

How do you change the color of a UIButton when you are pressing it?

I am wondering how can you can change the color of a UIButton when it is pressed. By default, a UIButton has a faded blue when you press it. How do I change this from faded to, for example purple, when I press it. How do I do this in Swift 4? Is there some sort of property I can change?
Swift 4.2
use this extension for button:
extension UIButton {
func setBackgroundColor(_ color: UIColor, forState controlState: UIControl.State) {
let colorImage = UIGraphicsImageRenderer(size: CGSize(width: 1, height: 1)).image { _ in
color.setFill()
UIBezierPath(rect: CGRect(x: 0, y: 0, width: 1, height: 1)).fill()
}
setBackgroundImage(colorImage, for: controlState)
}
}
and simply usage:
override func viewDidLoad() {
super.viewDidLoad()
let button = UIButton()
button.frame = CGRect(x: 150, y: 200, width: 200, height: 20)
button.setBackgroundColor(.red, forState: .normal)
button.setBackgroundColor(.blue, forState: .highlighted)
view.addSubview(button)
}
hope this make you smile :)
Use setTitleColor(_:for:) to set the title color (the first parameter) differently for the .normal and the .highlighted state (the second parameter).
See https://developer.apple.com/documentation/uikit/uibutton/1623993-settitlecolor
I think you can use setBackgroundImage function to archive that:
button.setBackgroundImage(UIImage(named: "PURPLE_IMAGE"), for: .highlighted)
You can set image for highlighted, selected, disable...etc
I know your question is to change the highlight background color, not the background image, but unfortunately it doesn't seems to have a direct way to do it. So my work around is to programmatically create an image of that color for the same effect (you may want to put it in UIImage extension):
let rect = CGRect(point: .zero, size: CGSize(width: 1, height: 1))
UIGraphicsBeginImageContextWithOptions(rect.size, false, 0.0)
let context = UIGraphicsGetCurrentContext()
context!.setFillColor(color.cgColor)
context!.fill(rect)
let img = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
If you want to change UIButton background color with click you can simply use backgroundColor property as shown below:
#IBAction func btnTapped(_ sender: UIButton) { //sender type should be UIButton
sender.backgroundColor = UIColor.purple
}
and if you want to set title color on click you can use setTitleColor property as shown below:
#IBAction func btnTapped(_ sender: UIButton) {
sender.setTitleColor(UIColor.purple, for: .highlighted)
}
Use .backgroundColor for set Color; var button_isActive for button press, UIView.animate
var button_isActive: Bool = false
#IBAction func btn_Button(_ sender: UIButton) {
if button_isActive {
UIView.animate(withDuration: 0.2) {
sender.backgroundColor = UIColor.clear
}
} else {
UIView.animate(withDuration: 0.2) {
sender.backgroundColor = UIColor.purple
}
}
button_isActive = !button_isActive
}
Caveat: Even after setting the background color
btn.backgroundColor = .red
The color changing was not displaying, took a while to figure out that I need to change uibutton configuration from "Filled" to "Default"
You can try this for button color change
#IBAction func btnPress(_ sender: UIButton) {
DispatchQueue.main.async {
self.yourButton.backgroundColor = .purple
}
}

Removing a UILabel programmatically after a button is pressed

I am trying to create/show a label when a button is pressed, and then delete/hide the same label when the same button is pressed again. I am trying to do this all programmatically in Swift.
I have tried using label.removeFromSuperview() but it doesn't seem to have any effect. However when i try removing the button in the same code location using button.removeFromSuperview()
var label = UILabel()
let labelImage = UIImage(named: "Strike Line.png")
/* to select checkmarked state */
func pressCheck() {
let image = UIImage(named: "Checkmark.png")
button.setBackgroundImage(image, for: UIControlState.normal)
button.addTarget(self, action:#selector(self.pressUnCheck), for: .touchUpInside)
self.view.addSubview(button)
textField1.textColor = UIColor.gray //change textfield to a gray color
label = UILabel(frame: CGRect(x : 31, y : 69, width: 200, height: 2))
label.backgroundColor = UIColor(patternImage: labelImage!)
self.view.addSubview(label)
}
func pressUnCheck()
{
let image = UIImage(named: "To Be Completed Circle.png")
button.setBackgroundImage(image, for: UIControlState.normal)
button.addTarget(self, action:#selector(self.pressCheck), for: .touchUpInside)
self.view.addSubview(button)
label.removeFromSuperview()
textField1.textColor = UIColor.black
}
Here is where i am trying to remove/hide the label.
Since this apparently was the fix I'll drop it in as an answer.
Add button.removeTarget(nil, action: nil, for: .allEvents) before you add any new targets to your button.
If you don't remove the current target it'll have multiple targets and be calling both pressCheck() and pressUnCheck() on each button press.
There's a few ways to handle this... If you just want to hide it you can use
label.isHidden = true - would hide the label.
label.isHidden = false - would show the label.

Swift UIButton .setTitle not working

I am programmatically creating a set of buttons on my VC. I am adding a target for the buttons when creating them and in the function that gets called I am changing the background image and trying to remove the title. However, the title is not changing but the background image is changing which doesn't make sense to me.
func createButton(xPos: Int, yPos: Int, width: Int, height: Int, buttonIndex: Int) -> UIButton {
var button = UIButton()
button.frame = CGRect(x: xPos , y: yPos, width: width, height: height)
button.userInteractionEnabled = true
button.layer.masksToBounds = true
var buttonImage = UIImage(named: "Display_Icon")
button.tag = buttonIndex
button.setBackgroundImage(buttonImage, forState: UIControlState.Normal)
button.setTitle("\(buttonIndex)", forState: UIControlState.Normal)
var titleColor = UIColor(red: 0.0, green: 104/255.0, blue: 178/255.0, alpha: 1.0)
button.setTitleColor(titleColor, forState: UIControlState.Normal)
button.addTarget(self, action: "screenSelected:", forControlEvents: UIControlEvents.TouchUpInside)
return button
}
func screenSelected(button: UIButton!) {
if hasError { hasError = false; return }
let screenIndex = button.titleLabel!.text!
if contains(buttonsSelectedArray, screenIndex) {
return
}
buttonsSelectedArray.append(screenIndex)
var buttonImage = UIImage(named: "DisplaySelected_Icon")
button.setBackgroundImage(buttonImage, forState: UIControlState.Normal)
button.setTitle("", forState: UIControlState.Normal)
var titleColor = UIColor.clearColor()
button.setTitleColor(titleColor, forState: UIControlState.Normal)
Try this,
Problem that u add target button in old method(Obj-c)
func createButton(xPos: Int, yPos: Int, width: Int, height: Int, buttonIndex: Int) -> UIButton {
....
....
button.addTarget(self, action: #selector(UIViewController. screenSelected(_:)), for: UIControlEvents.touchUpInside)
return button
}
#IBAction func screenSelected(button: UIButton!) {
if hasError { hasError = false; return }
let screenIndex = button.titleLabel!.text!
if contains(buttonsSelectedArray, screenIndex) {
return
}
buttonsSelectedArray.append(screenIndex)
var buttonImage = UIImage(named: "DisplaySelected_Icon")
button.setBackgroundImage(buttonImage, forState: .normal)
button.setTitle("", forState: .normal)
var titleColor = UIColor.clearColor()
button.setTitleColor(titleColor, forState: .normal)
}
You need to set your button title like this
button.setTitle("Button Title Here", for: UIControlState.normal)
IOS no longer supports using
button.titleLabel?.text= "Button Title"
because you are required to set your title with its UIControlState which is either selected, normal, highlighted or whatever it is.
Please see the documentation from this https://developer.apple.com/reference/uikit/uibutton/1624018-settitle?language=objc

How to scale image and center it on a UIButton in Swift?

var button = UIButton.buttonWithType(UIButtonType.Custom) as UIButton
var image = UIImage(named: "myimage.png") as UIImage!
button.frame = CGRectMake(0, 0, 100, 100)
button.setImage(image, forState: .Normal)
I have an image that I've set on my button, but I'd like to scale it to be smaller than the button (for example the image should be 50,50) and center in the button. How might I do this in Swift?
Xcode 8.3.1 • Swift 3.1
let button = UIButton(type: .custom)
let image = UIImage(named: "myimage.png")
func buttonTouchDown(_ button: UIButton) {
print("button Touch Down")
}
override func viewDidLoad() {
super.viewDidLoad()
button.frame = CGRect(x: 0, y: 0 , width: 100, height: 100)
button.backgroundColor = .clear
button.addTarget(self, action: #selector(buttonTouchDown), for: .touchDown)
button.setTitle("Title", for: .normal)
button.setTitleColor(.black, for: .normal)
button.setImage(image, for: .normal)
button.imageEdgeInsets = UIEdgeInsetsMake(25,25,25,25)
view.addSubview(button)
}
Swift 5, Swift 4, Swift 3
var image = UIImage(named: "myimage") as UIImage!
btnetc.setImage(image, for: .normal)
btnetc.imageView?.contentMode = .scaleAspectFill
or
btnetc.imageView?.contentMode = .scaleAspectFit
or
btnetc.imageView?.contentMode = .scaleToFill
Ther is a much easier way to do this where you don't have to deal with content insets. Here its is:
var button = UIButton.buttonWithType(UIButtonType.Custom) as UIButton
var image = UIImage(named: "myimage.png") as UIImage!
button.frame = CGRectMake(0, 0, 100, 100)
button.setImage(image, forState: .Normal)
button.contentMode = .center
button.imageView?.contentMode = .scaleAspectFit
Or via XIB after selecting your UIButton.
Just make sure your insets are all the same.
Xcode 13, Swift 5
Using storyboard, select the button, then in the size inspect click the dropdown on size just above Content inset. There is a list of sizes to select from, and this will adjust your image size(if you use system image). The default size is already set when you added the button on the storyboard to the View Controller.

Swift- How to Display Image over Button?

I'm trying to display an Image over a button, I'm getting BLUE PRINT of Image over button, I have tried so far this-
override func viewDidLoad()
{
super.viewDidLoad()
var birdTexture1 = UIImage(named: "fish.png") as UIImage
button1.frame = CGRectMake(100, 10, 50, 150)
button1.setImage(birdTexture1, forState: .Normal)
button1.setTitle("Testing", forState: UIControlState.Normal)
button1.addTarget(self, action: "btnAction:", forControlEvents: UIControlEvents.TouchUpInside)
self.view.addSubview(button1)
// Do any additional setup after loading the view, typically from a nib.
}
By above code, I m getting, the following output
But the Actual Image is this-
I think your UIButton needs to be of type UIButtonTypeCustom, rather than UIButtonTypeSystem. You either constructed it as such, or need to update the UIButton's properties in interface builder.
More info: https://developer.apple.com/library/ios/documentation/uikit/reference/UIButton_Class/UIButton/UIButton.html#//apple_ref/occ/clm/UIButton/buttonWithType:
i think replace this code:
let birdTexture1 = UIImage(named: "fish.png")! as UIImage
let button1:UIButton=UIButton(frame:CGRectMake(100, 50, 50, 150))
button1.setBackgroundImage(birdTexture1, forState: .Normal)
button1.setTitle("Testing", forState: .Normal)
button1.addTarget(self, action: #selector(ViewController.btnActionClick(_:)), forControlEvents: UIControlEvents.TouchUpInside)
self.view.addSubview(button1)
#IBAction func btnActionClick(sender:AnyObject){
}
and also add to image in target