how to change a UIbutton in a collection view? - swift

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

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 to implement checkbox in swift?

I am using this code for implementing checkbox but it is not working. Can anyone tell where I went wrong?
#IBAction func tapped(_ sender: UIButton){
if (checkBox.isSelected == false){
checkBox.setImage(UIImage(named: "circle_radio_selected"), for: .normal)
checkBox.isSelected = true;
} else {
checkBox.setImage(UIImage(named: "circle_radio_unselected"), for: .normal)
checkBox.isSelected = false;
}
The easy way of doing this is to already assign the images for different UIControl.State. I don't know if you have created this button using storyboard/xib or have created it programatically. I would do it like this:
private let checkbox: UIButton = {
let button = UIButton()
button.setImage(UIImage(named: "circle_radio_selected"), for: .selected)
button.setImage(UIImage(named: "circle_radio_unselected"), for: .normal)
return button
}()
Now, once your IBAction is called:
I am using this code for implementing checkbox but it is not working. Can anyone tell where I went wrong?
#IBAction func tapped(_ sender: UIButton){
checkBox.isSelected = sender.isSelected
// Now you have already set the images according to control state. Once it is selected it will change the image and when it is not selected it will become normal and select the other image
}
Also, it will be best if you can create a Constants file and add these named strings there.
You can set the images for normal/selected states in the interface builder, or you can do it programmatically, e.g.
override func viewDidLoad() {
super.viewDidLoad()
checkBox.setImage(UIImage(named: "circle_radio_unselected"), for: .normal)
checkBox.setImage(UIImage(named: "circle_radio_selected"), for: .selected)
}
Then your tap function can easily toggle the button state.
#IBAction func tapped(_ sender: UIButton) {
checkBox.isSelected.toggle()
}

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

How to change UIButton's image every time it is pressed

How can I make a UIButton change image from A to B and again B to A, every time it's pressed?
Not as .normal to .highlighted, but permanent.
I've tried the .highlighted method because I can't find the code for permanent, here's my code:
func ChangeButton() {
Button.setImage(A, for: .normal)
Button.setImage(B, for: .highlighted)
Thanks for mentions of setBackgroundImage to Xavier L. from the other answer.
Try the following code:
import UIKit
class ViewController: UIViewController {
#IBOutlet var button: UIButton!
var buttonActive = false
override func viewDidLoad() {
super.viewDidLoad()
button.setBackgroundImage(UIImage(named: "apple"), for: .normal)
}
#IBAction func buttonPressed() {
if buttonActive {
button.setBackgroundImage(UIImage(named: "apple"), for: .normal)
} else {
button.setBackgroundImage(UIImage(named: "pineapple"), for: .normal)
}
buttonActive = !buttonActive
}
}
And your storyboard should look like that:
N.B. On Stack Overflow you should perform some actions before asking. Try to include some code you tried.
I recommend changing the backgroundImage because it's scaled automatically, and the button text in front won't get covered.
If it's a custom button, within its initializer:
self.addTarget(self, action: #selector(*yourfunctoswitchimages*), for: .touchUpInside)
... and then that yourfunctoswitchimages can just check what the current background image is, and switch it accordingly.
If it's not a custom button, add a target to it in viewDidLoad or something. Here's a lot of sample code.
In your viewDidLoad()
yourButt.addTarget(self, action: #selector(switcheroo), for: .touchUpInside)
Another func in your view controller:
func switcheroo()
{
if yourButt.currentBackgroundImage == image1
{
yourButt.setBackgroundImage(image2), for: .normal)
}
else { // ...set image to image1 }
}
yourButt would be a property of your view controller of course, that way it's accessible to the viewDidLoad() and to other funcs within it.