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

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()
}

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 do I save a buttons image state in Swift?

I have this like button and when the user pressed on it the image changed to another image. How would I be able to save the new image when I close my app and open it up again. I have the code below and Im using NSUserDefaults but its not saving the changed image. Here is the code:
override func viewDidLoad() {
super.viewDidLoad()
UserDefaults.standard.set(true, forKey: "Change")
}
#IBAction func addToLikes(_ sender: Any) {
//progressView.isHidden = false
if UserDefaults.standard.bool(forKey: "Change") {
likedButton.setImage(UIImage(named: "selected_star"), for: .normal)
}
}
Got it to work:
override func viewDidLoad() {
super.viewDidLoad()
if UserDefaults.standard.bool(forKey: "starSelected") {
likedButton.setImage(UIImage(named: "selected_star"), for: .normal)
print("star selected")
}
if UserDefaults.standard.bool(forKey: "starNotSelected") {
likedButton.setImage(UIImage(named: "not_selected_star"), for: .normal)
print("star not selected")
}
}
}
#IBAction func addToLikes(_ sender: Any) {
//progressView.isHidden = false
likedButton.isSelected = !likedButton.isSelected
if likedButton.isSelected {
print("I am selected.")
likedButton.setImage(UIImage(named: "selected_star"), for: .normal)
UserDefaults.standard.set(false, forKey: "starNotSelected")
UserDefaults.standard.set(true, forKey: "starSelected")
} else {
likedButton.setImage(UIImage(named: "not_selected_star"), for: .normal)
UserDefaults.standard.set(false, forKey: "starSelected")
UserDefaults.standard.set(true, forKey: "starNotSelected")
print("I am not selected.")
}

how to change a UIbutton in a collection view?

I have a collection view with a like button on each. I also have a refresh button, although I do not know if it is relevant.
How do I change the image of the button after it is pressed?
I tried adding this, but nothing happens:
#IBOutlet weak var likeNot: UIButton!
#IBAction func likeIt(_ sender: UIButton) {
func viewDidLoad() {
super.viewDidLoad()
self.likeNot.setImage(UIImage(imageLiteralResourceName: "like"), for: .normal)
self.likeNot.setImage(UIImage(imageLiteralResourceName: "likeSelected"), for: .selected)
// likeIt.setImage(UIImage(named: "likeSelected"), for: .highlighted)
}
}
I also have a refresh button. Will that interferes?
#IBAction func refresh_TouchUpInside(_ sender: Any) {
loadTopPosts()
}
func loadTopPosts() {
ProgressHUD.show("Loading...", interaction: false)
self.posts.removeAll()
self.collectionView.reloadData()
Api.Post.observeTopPosts { (post) in
self.posts.append(post)
self.collectionView.reloadData()
ProgressHUD.dismiss()
}
}
Your likeIt(_:) function is not doing anything because you're only defining another function for some reason inside of it (viewDidLoad). Just call setImage(_:for:) on the buttons without the inner function:
#IBAction func likeIt(_ sender: UIButton) {
self.likeNot.setImage(UIImage(imageLiteralResourceName: "like"), for: .normal)
self.likeNot.setImage(UIImage(imageLiteralResourceName: "likeSelected"), for: .selected)
// likeIt.setImage(UIImage(named: "likeSelected"), for: .highlighted)
}

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
}
}

Changing image of UIButton via click - 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
}
}