Changing image of UIButton via click - Swift - swift

Im getting an error with this code..
What it should do: When user taps button, the image changes to checked, taps again, changes to Unchecked.
Im getting the error: AnyObject doesnt have member names 'setImage ...
#IBAction func tick(sender: AnyObject) {
if let image = UIImage(named:"Unchecked") {
sender.setImage(UIImage(named:"Checked.png"), forControlState: .Normal)
}
if let image = UIImage(named:"Checked") {
sender.setImage( UIImage(named:"Unchecked.png"), forControlState: .Normal)
}
}

You only needs to change (sender:AnyObject) to (sender:UIButton)
as below
#IBAction func tick(sender: UIButton) {
if let image = UIImage(named:"Unchecked") {
sender.setImage(UIImage(named:"Checked.png"), forControlState: .Normal)
}
if let image = UIImage(named:"Checked") {
sender.setImage( UIImage(named:"Unchecked.png"), forControlState: .Normal)
}
}

You have to explicitly tell your compiler that sender is a UIButton and not AnyObject type.
#IBAction func tick(sender: AnyObject) {
if let button = sender as! UIbutton {
if let image = UIImage(named:"Unchecked") {
button.setImage(UIImage(named:"Checked.png"), forControlState: .Normal)
}
if let image = UIImage(named:"Checked") {
button.setImage( UIImage(named:"Unchecked.png"), forControlState: .Normal)
}
}
}

You can do it this way:
var checked = false
#IBAction func tick(sender: UIButton) {
if checked {
sender.setImage( UIImage(named:"Unchecked.png"), forState: .Normal)
checked = false
} else {
sender.setImage(UIImage(named:"Checked.png"), forState: .Normal)
checked = true
}
}

Related

how to get value from radio button to a variable in swift 5

Need to save ther value from the radio button to a variable
#IBOutlet weak var userButton: UIButton!
#IBOutlet weak var propertyButton: UIButton!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
#IBAction func btClicked (sender: UIButton) {
let buttonArray = [userButton , propertyButton]
buttonArray.forEach {_ in
$0?.isSelected = false
}
}
create a variable to store the value of button
var strVal = ""
create two different outlet for both button
#IBAction func btnUserClicked(_ sender: UIButton) {
setValue(isUser: true)
}
#IBAction func btnPropertyOwnerClicked(_ sender: UIButton) {
setValue(isUser: false)
}
the setValue(isUser : Bool) method will store your selected button value and change image of button according to selection
func setValue(isUser : Bool){
if isUser{
strVal = "User"
btnUser.setImage(UIImage(named: "circle-fill"), for: .normal)
btnPropertyOwner.setImage(UIImage(named: "circle"), for: .normal)
}
else{
strVal = "Property Owner"
btnPropertyOwner.setImage(UIImage(named: "circle-fill"), for: .normal)
btnUser.setImage(UIImage(named: "circle"), for: .normal)
}
}
the image 'circle' is your default image that is already on button and the image 'circle-fill' is to indicate whether or not your button is selected.
or you can use sender.tag property of button :
#IBAction func btnUserClicked(_ sender: UIButton) {
//setValue(isUser: true)
if(sender.tag == 0){
strVal = "user"
btnUser.setImage(UIImage(named: "circle-fill"), for: .normal)
btnPropertyOwner.setImage(UIImage(named: "circle"), for: .normal)
}
else{
strVal = "property user"
btnPropertyOwner.setImage(UIImage(named: "circle-fill"), for: .normal)
btnUser.setImage(UIImage(named: "circle"), for: .normal)
}
}

How should I set button's image in same action?

In my ViewController,
there is multiple buttons connected to the same action
my button is like check or uncheck
I have tried below
My action is triggered, but image didn't change
var uncheckBoxImage = UIImage(named: "uncheckBox")
var checkBoxImage = UIImage(named: "checkBox")
override func viewDidLoad() {
super.viewDidLoad()
for button in buttons{
button?.setImage(uncheckBoxImage, for: .normal)
//every button I set uncheckBoxImage first.
}
}
#IBAction func btnAction(_ sender: UIButton) { //connect every button
if sender.imageView == checkBoxImage {
sender.setImage(uncheckBoxImage, for: .normal)
}else {
sender.setImage(checkBoxImage, for: .normal)
}
}
I also tried below, but it can't process multiple button
var cube:Bool = false
#IBAction func btnAction(_ sender: Any) {
cube = !cube
if cube {
sender.setImage(checkBoxImage, for: .normal)
} else {
sender.setImage(uncheckBoxImage, for: .normal)
}
}
How should I fix these situation ?
Like it has some questions for you
And you just need to click to be check or click again to be uncheck
The trick is to use the selectedState for buttons.
Set both images for .normal and .selected state:
button?.setImage(uncheckBoxImage, for: .normal)
button?.setImage(checkBoxImage, for: .selected)
then, in IBAction:
#IBAction func btnAction(_ sender: UIButton) {
sender.isSelected = !sender.isSelected
...
}
You should implement different button's state, it will change image automatically
var uncheckBoxImage = UIImage(named: "uncheckBox")
var checkBoxImage = UIImage(named: "checkBox")
override func viewDidLoad() {
super.viewDidLoad()
for button in buttons{
button?.setImage(uncheckBoxImage, for: .normal)
button?.setImage(checkBoxImage, for: .selected)
}
}
#IBAction func btnAction(_ sender: UIButton) { //connect every button
sender.isSelected = !sender.isSelected
}
Hi Please try with a tintcolor if that works
var uncheckBoxImage = UIImage(named: "uncheckBox")
var checkBoxImage = UIImage(named: "checkBox")
override func viewDidLoad() {
super.viewDidLoad()
for button in buttons{
button?.setImage(uncheckBoxImage, for: .normal)
button?.tintColor = UIColor.clear
}
}
#IBAction func btnAction(_ sender: UIButton) {
if sender.tintColor == UIColor.clear {
sender.setImage(checkBoxImage, for: .normal)
sender.tintColor = UIColor.green
}else if sender.tintColor == UIColor.green {
sender.setImage(uncheckBoxImage, for: .normal)
sender.tintColor = UIColor.clear
}
}
For just two states, abstracting "normal" and "selected", it's better to use the above answers, but if you need to handle multiple cases, you can use <#UIButton#>.currentImage!.isEqual(to: foo), to compare images and use only .normal state.
This is an example:
#IBAction func btnAction(_ sender: UIButton) {
if sender.currentImage != nil && sender.currentImage!.isEqual(UIImage(named: "a")) {
sender.setImage(UIImage(named: "b"), for: .normal)
} else {
sender.setImage(UIImage(named: "a"), for: .normal)
}
}
If you want multiple selection then you can use.
override func viewDidLoad() {
super.viewDidLoad()
for button in buttons {
button.setImage(UIImage(named: "uncheckBox"), for: .normal)
button.setImage(UIImage(named: "checkBox"), for: .selected)
button.tintColor = .clear
}
}
#IBAction func btnAction(_ sender: UIButton) {
// toggle automatic changes selection state
sender.isSelected.toggle()
}

Creating a checkbox programmatically using images as the UIButtons background

I have seen multiple questions on how to implement a checkbox by just changing the background image when clicked, but I don't understand why the checkbox only shows when I add it to my ViewController setupViews.
It simply will not show up or change when I have all the functionality in my actionButton function. Should i be using a protocol and delegate set up to get my button showing changing when clicked? Below is my code, I am hoping someone can shed some light as to what I am missing here?
class MainMenuViewController: UIViewController {
let clickingCheckbox = ClickingCheckbox()
var checkbox = UIImage(named: "Checked_Checkbox")
var empty_checkbox = UIImage(named:"Empty_Checkbox")
var isBoxClicked: Bool!
override func viewDidLoad() {
super.viewDidLoad()
setupViews()
}
func setupViews() {
self.backgroundImage.addSubview(contentView)
self.contentView.addSubview(clickingCheckbox)
clickingCheckbox.snp.makeConstraints { (make) in
make.top.equalTo(signInButton.snp.bottom).offset(-MainMenuViewController.padding)
make.leading.equalTo(buttonView)
make.width.equalTo(signInButton).multipliedBy(0.2)
make.height.equalTo(clickingCheckbox.snp.width)
}
clickingCheckbox.addTarget(self, action: #selector(buttonAction(_:)), for: .touchUpInside)
clickingCheckbox.setImage(empty_checkbox, for: UIControlState.normal) #The checkbox only shows on screen if I put it here, however it does nothing when clicked!
}
#objc func buttonAction(_ sender: ClickingCheckbox) {
if isBoxClicked == true {
isBoxClicked = false
}else{
isBoxClicked = true
}
if isBoxClicked == true {
sender.setImage(checkbox, for: UIControlState.selected)
}else{
sender.setImage(empty_checkbox, for: UIControlState.normal)
}
print("test")
}
In my Class I have.....
class ClickingCheckbox: UIButton {
override func draw(_ rect: CGRect) {
super.draw(rect)
}
}
I have tried keeping the buttonAction functionality in the class, but that didn't work, I have tried a multiple different ways but can't get my head around how to show it working. All other advice is given to implement using IBOutlets so this would be really helpful for me to understand. Thanks
Try something like this:
class ClickingCheckbox: UIButton {
convenience init() {
self.init(frame: .zero)
self.setImage(UIImage(named: "Empty_Checkbox"), for: .normal)
self.setImage(UIImage(named: "Checked_Checkbox"), for: .selected)
self.addTarget(self, action: #selector(buttonTapped), for: .touchUpInside)
}
#objc private func buttonTapped() {
self.isSelected = !self.isSelected
}
}

Change color of a button on touch...and then back again

I currently have a UIButton that changes from red to green when selected. How can I implement the reverse, so that it goes back to the original state when selected again? Below is my current code:
#IBAction func button1press(_ sender: AnyObject) {
(sender as! UIButton).backgroundColor = UIColor.green
}
When tapping the button update the selected state, i.e:
This way you know which state the button is at.
If you wish to edit other properties, such as text color, font, image etc... you can just use the storyboard "State Config" option, and make different themes for different states (within the IB's limits)
#IBAction func button1press(_ sender: AnyObject) {
if let button : UIButton = sender as? UIButton
{
button.isSelected = !button.isSelected
if (button.isSelected)
{
button.backgroundColor = UIColor.green
}
else
{
button.backgroundColor = UIColor.red
}
}
}
On each press, check the current background color, and change it to the other one.
#IBAction func button1press(_ sender: UIButton) {
if let button = sender as? UIButton {
if button.backgroundColor == UIColor.green {
button.backgroundColor = UIColor.red
}
else if button.backgroundColor == UIColor.red {
button.backgroundColor = UIColor.green
}
}
}

How to change the image of a navigation button when tapped 3 times?

I need to change the Image of a UIButton in my NAV bar when a user taps it 3 times. Each tap displays a different UIImage and its corresponding collection view. I got the animated collection view working perfectly, but...
How do I get the button images to change in Swift?
I've tried multiple methods and can't seem to get it to work, for example:
#IBAction func buttonTapped(sender: UIButton) {
if let myButton = UIImage(named:"btn1") {
sender.setImage(myButton, forState: .Normal)
}
if let myButton = UIImage(named:"btn2") {
sender.setImage(myButton, forState: .Normal)
}
if let myButton = UIImage(named:"btn3") {
sender.setImage(myButton, forState: .Normal)
}
}
There are lots of posts relating to changing a uibutton for two states, e.g., stopwatch or play/pause, but I need 3 states in a navigation bar.
Thanks!
I think there are two easy ways to do this:
You can set a variable Int in your class and just count it up until it is 2 and then set it again to 0 like this:
var buttonCounter: Int = 0
#IBAction func buttonTapped(sender: UIButton) {
if buttonCounter == 0{
let myButton = UIImage(named:"btn1")
sender.setImage(myButton, forState: .Normal)
buttonCounter++
}
else if buttonCounter == 1 {
let myButton = UIImage(named:"btn2")
sender.setImage(myButton, forState: .Normal)
buttonCounter++
}
else {
let myButton = UIImage(named:"btn3")
sender.setImage(myButton, forState: .Normal)
buttonCounter = 0
}
}
You could do nearly the same but instead of using a variable you can use the .tag attribute of the UIButton. The tag is an integer and is normally used to find out which button calls the IBAction but you have only one button calling the function so you can use it like this:
#IBAction func buttonTapped(sender: UIButton) {
if sender.tag == 0{
let myButton = UIImage(named:"btn1")
sender.setImage(myButton, forState: .Normal)
sender.tag++
}
else if sender.tag == 1 {
let myButton = UIImage(named:"btn2")
sender.setImage(myButton, forState: .Normal)
sender.tag++
}
else {
let myButton = UIImage(named:"btn3")
sender.setImage(myButton, forState: .Normal)
sender.tag = 0
}
}