Removed Selected State on Button While Clicking a Different Button (Swift) - ios

I'm trying to figure out the logic in toggling button states in Swift. The concept is very simple:
I have three buttons on the screen.
When I click one button, it toggles to a 'selected' state
When I click a different button, I want it to toggle the currently selected button to a 'non-selected' state and toggle the new button to 'selected'
I have this function I use on TouchUpInside for the buttons on the screen but at the moment it's possible to have them all 'selected' which I don't want:
func highlightTrack(sender:UIButton){
if(!sender.selected){
sender.selected = true
sender.backgroundColor = UIColor.blueColor()
} else {
sender.selected = false
}
}
I come from the world of Javascript so I may just have my logic crossed up but is there a way to detect currently selected buttons on the screen and turn them off or is this closer to a 'radio' button type logic?
My issue is that these buttons are created programmatically depending on certain conditions so technically I'm not supposed to be created IBOutlets on the fly like that correct (IB meaning 'Interface Builder'?)?
Thanks for your help!

func highlightTrack(sender:UIButton) {
if sender.isSelected {
return
}
btn1.isSelected = false
btn2.isSelected = false
sender.isSelected = true
}

Connect following action function with all your three buttons using TouchUpInside control event.
button1.addTarget(self, action: #selector(self.highlightTrack(button:)), for: .touchUpInside)
button2.addTarget(self, action: #selector(self.highlightTrack(button:)), for: .touchUpInside)
button3.addTarget(self, action: #selector(self.highlightTrack(button:)), for: .touchUpInside)
#IBAction func highlightTrack(button: UIButton) {
if button.isSelected {
return
}
button1.isSelected = false
button1.backgroundColor = UIColor.white
button2.isSelected = false
button2.backgroundColor = UIColor.white
button3.isSelected = false
button3.backgroundColor = UIColor.white
button.isSelected = true
button.backgroundColor = UIColor.blue
}
Another solution:
#IBAction func highlightTrack(button: UIButton) {
if button.isSelected {
return
}
updateButtionSelectionState(button: button, isSelected: (button == button1))
updateButtionSelectionState(button: button, isSelected: (button == button2))
updateButtionSelectionState(button: button, isSelected: (button == button3))
}
func updateButtionSelectionState(button: UIButton, isSelected: Bool) {
button.isSelected = isSelected
button.backgroundColor = isSelected ? UIColor.blue : UIColor.white
}

Related

How to select one checkbox at a time in swift?

I have implemented four checkboxes. Now, I want to select one checkbox at a time and if there's other checkbox selected, I want it deselected at the same time.
This is what I've tried but it selects all the checkboxes.
#IBAction func checkboxTapped(_ sender:UIButton){
if (sender.isSelected == false){
sender.setImage(UIImage(named: "selected"), for: UIControl.State.normal)
sender.isSelected = true;
} else {
sender.setImage(UIImage(named: "unselected"), for: UIControl.State.normal)
sender.isSelected = false;
}
}
Here, I have given same IBAction connection to all the checkboxes.
First create a set up function that sets the corresponding image for the button state.
(All code below was created in a playground so it might be a little different than yours)
private func setUp(button: UIButton) {
button.setImage(UIImage.init(systemName: "checkmark.circle"), for: .selected)
button.setImage(UIImage.init(systemName: "xmark.circle"), for: .normal)
button.addTarget(self, action: #selector(checkboxTapped), for: .touchUpInside) //Not needed if you use a storyboard
}
Then call it from viewDidLoad in your view controller (I have my buttons in an array buttons)
override func viewDidLoad() {
super.viewDidLoad()
buttons.forEach {
setUp(button: $0)
self.view.addSubview($0) //Not needed if you use a storyboard
}
buttons[0].isSelected = true
And then check your action method so it updates all buttons properly
#IBAction func checkboxTapped(_ sender:UIButton){
for button in buttons {
button.isSelected = false
}
sender.isSelected = true
}
If you are not using an array then replace my loops with calls to the individual buttons

Swift create custom logic for radio button

I have four custom UIButton, I applied button image radio (checked and checked). four button I have separate action method I can change the Image easily but if I checked first button another three button need uncheck. it should react like radio button.
Here, below my code
#IBAction func first_scheme(_ sender: Any) {
bRec = !bRec
if (bRec == true) {
firstscheme_button.setImage(UIImage(named: "uncheck.png"), for: .normal)
} else {
firstscheme_button.setImage(UIImage(named: "check.png"), for: .normal)
}
}
If you have 4 radio buttons at all times, you can put them in an array.
var radioButtons: [ButtonType] = [r1, r2, r3, r4]
You can now access the button in a loop and set the values for the other button to 'unchecked'.
func setRadioButtons(button: ButtonType) {
for radioButton in radioButtons {
if radioButton !== button {
radioButton.setImage(UIImage(named: "uncheck.png"), for: .normal)
}
}
}
#IBAction func first_scheme(_ sender: Any) {
bRec = !bRec
if bRec {
firstscheme_button.setImage(UIImage(named: "uncheck.png"), for: .normal)
} else {
firstscheme_button.setImage(UIImage(named: "check.png"), for: .normal)
}
setRadioButtons(button: sender)
}
alternate method
If all you want to do is check the button clicked and uncheck the other buttons, the logic is simpler.
Create the common action for all radio buttons as well create the IBOutletcollection for your all UIButtons ,
var radioButtons: [UIButton] = [r1, r2, r3, r4]
finally execute the common method as
func setRadioButtons(button: UIButton) {
for getradioButton in radioButtons {
getradioButton.setImage(UIImage(named: "uncheck.png"), for: .normal)
}
button.setImage(UIImage(named: "check.png"), for: .normal)
}
I suggest you set tags on the buttons with the simple tag property, and then you save it from a generic listener.
//first button selected
var lastTag = 0
#IBAction func first_scheme(_ sender: UIButton) {
buttonArray[lastTag].setImage(UIImage(named: "uncheck.png"), for: .normal)
lastTag = sender.tag
sender.setImage(UIImage(named: "check.png"), for: .normal)
}
You Can override isSelected variable in the custom UIButton and set the image depend on the isSelected value.
class customButton: UIButton {
override var isSelected: Bool {
willSet {
self.setImage(UIImage.init(named: "checked"), for: .normal)
}
didSet {
self.setImage(UIImage.init(named: "unchecked"), for: .normal)
}
}
}
After making 4 IBOutlets and 4 IBActions for the four custom UIButtons. you can easily select and unselect the buttons and apply your custom behaviour.
#IBAction func firstButtonAction(_ sender: Any) {
if let button = sender as? customButton {
button.isSelected = !button.isSelected
}
secondButton.isSelected = false
thirdButton.isSelected = false
fourthButton.isSelected = false
}

Make multiple buttons highlight when touch begins

I have placed three buttons together in a view each of which will have a different profile image. I need all three buttons to highlight when touch begins on any individual one so that the three together appear to be one button. I have tried the following code but it does not work. Any ideas?
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(normalTap))
tapGesture.numberOfTapsRequired = 1
friendsBtn1.addGestureRecognizer(tapGesture)
func normalTap(sender: UITapGestureRecognizer){
if sender.state == .began {
friendsBtn2.isHighlighted = true
friendsBtn3.isHighlighted = true
}
if sender.state == .ended {
friendsBtn2.isHighlighted = false
friendsBtn3.isHighlighted = false
}
print("Normal tap")
}
i think no need to UITapGesture you can manage like this way.
First you need to set highlighted image to the button And Setup button event as per bellow.
override func viewDidLoad() {
super.viewDidLoad()
friendsBtn2.setImage(UIImage(named: "highlighted.png"), for: .highlighted)
friendsBtn3.setImage(UIImage(named: "highlighted.png"), for: .highlighted)
friendsBtn1.addTarget(self, action: #selector(YourViewController.touchDownEvent), for: .touchDown)
friendsBtn1.addTarget(self, action: #selector(YourViewController.touchUpInsideEvent), for: .touchUpInside)
}
After that add method touchDownEvent(),touchUpInsideEvent() in your ViewController.
func touchDownEvent() {
self.allButtonHighlighted(fleg: true)
}
func touchUpInsideEvent() {
self.allButtonHighlighted(fleg: false)
}
func allButtonHighlighted( fleg: Bool) {
friendsBtn2.isHighlighted = fleg
friendsBtn3.isHighlighted = fleg
}
I hope it will Works.
I did solve the problem. Here is the code.
[friendsBtn1, friendsBtn2, friendsBtn3].forEach { button in
button?.addTarget(self, action:#selector(highlightAllButtons(sender:)), for: .touchDown)
button?.addTarget(self, action:#selector(unhighlightAllButtons(sender:)), for: [.touchUpInside, .touchUpOutside])
}
func highlightAllButtons(sender: UIButton) {
[friendsBtn1, friendsBtn2, friendsBtn3].forEach { button in
button.isHighlighted = true
}
}
func unhighlightAllButtons(sender: UIButton) {
[friendsBtn1, friendsBtn2, friendsBtn3].forEach { button in
button.isHighlighted = false
}
}
Try [button setSelected:YES]; for all the three buttons in your button action.

how to create single selection check box in swift2?

import UIKit
class CheckBox: UIButton {
// Images
let checkedImage = UIImage(named: "check-sign.png")! as UIImage
let uncheckedImage = UIImage(named: "blank-square.png")! as UIImage
// Bool property
var isChecked: Bool = false {
didSet{
if isChecked == true {
self.setImage(checkedImage, forState: .Normal)
} else {
self.setImage(uncheckedImage, forState: .Normal)
}
}
}
override func awakeFromNib() {
self.addTarget(self, action: "buttonClicked:", forControlEvents: UIControlEvents.TouchUpInside)
self.isChecked = false
}
func buttonClicked(sender: UIButton) {
if sender == self {
isChecked = !isChecked
}
}
}
I was trying to implement checkboxes in Swift 2. I was referring to How to create radio buttons and checkbox in swift (iOS)?.
But my requirement is I want to implement single selection checkbox. I am not sure how to group the buttons via IB to make it single selectable.
Any suggestion?
Currently it is multiple selectable, I want to make it single selectable.
You can do it with UITableView and custom cells ,and change tableView.allowsMultipleSelection = flase.
Ex : You can do that by setting the accessoryType on the selected UITableViewCell instances to UITableViewCelAccessoryCheckmark.
To deselect the row, set it back to UITableViewCellAccessoryNone.

Multiple UIButtons only one can be selected - subclass in swift

I have written a subclass that selects and deselects buttons. I have put this subclass on around 5 buttons in a View Controller.
I want to amend the code so that if the user selects one and then selects another the first one gets deselected.
I was thinking of using the .tag on the button to count which buttons has been selected and remove the selection when the next button is pressed.
Here is the code :
thanks
class ChangeColour: UIButton {
var buttontagpressed: Int = 0
var isChecked:Bool = false{
didSet{
if isChecked == true {
self.backgroundColor = UIColor(red:0.27, green:0.29, blue:0.31, alpha:1.0)
self.setTitleColor(UIColor.whiteColor(), forState: .Normal)
buttontagpressed = self.tag
}
else
{
self.backgroundColor = UIColor(red:0.09, green:0.83, blue:0.56, alpha:1.0)
self.setTitleColor(UIColor(red:0.24, green:0.24, blue:0.24, alpha:1.0), forState: .Normal)
}
}
}
override func awakeFromNib() {
self.addTarget(self, action: "buttonselected:", forControlEvents: UIControlEvents.TouchUpInside)
self.isChecked = false
}
func buttonselected (sender:UIButton) {
buttontagpressed = self.tag
if (sender == self)
{
if isChecked == true
{
isChecked = false
}
else
{
isChecked = true
}
}
}
}
Rather than using tag (which I think is quite an ugly solution) I would be inclined to add a property to your class which keeps a reference of the previously selected button. This solution would be much more elegant - Or you could use UINotificationCenter to broadcast a message to all buttons to initiate the deselect.

Resources