1

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!

Krunal
  • 77,632
  • 48
  • 245
  • 261
MillerMedia
  • 3,651
  • 17
  • 71
  • 150
  • You should add IBOutlets for each button, and when the method is called, check the state of each IBOutlet. – Matthew S. Feb 01 '16 at 07:58
  • 1
    Even better, use a referencing outlet collection (an array) and then in your `highlightTrack` you simply iterate through the array. If the element is == `sender` then highlight the button else remove the highlight. – Paulw11 Feb 01 '16 at 08:01
  • @MatthewS. 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'?)? Or am I incorrect in assuming that? – MillerMedia Feb 01 '16 at 08:01
  • 1
    If you are creating them programmatically then it is the same thing, you just don't need the `@IBOutlet` syntax to help the compiler connect them. You can just create them and store references in an array property – Paulw11 Feb 01 '16 at 08:44

2 Answers2

0
func highlightTrack(sender:UIButton) {
    if sender.isSelected {
        return
    }

    btn1.isSelected = false
    btn2.isSelected = false
    sender.isSelected = true
}
Pang
  • 9,564
  • 146
  • 81
  • 122
0

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
}
Krunal
  • 77,632
  • 48
  • 245
  • 261