Search code examples
iosswiftxcodebuttonuistackview

How can I deselect a button when other consecutive button is pressed?


I'm creating a test that has 5 buttons, each button corresponds to a specific color, the problem is that when I select a consecutive 2nd button, the previous button is still selected, how can I make my code select only one button at a time and deselect the previous one?

How can I fix this?

This is my code

class ViewController: UIViewController {
    
    

    var buttonPressed: Bool = false
    
    @IBOutlet weak var button1: UIButton!
    @IBAction func buttonAction1(_ sender: UIButton) {
        if buttonPressed {
            
            buttonPressed = false
            button1.setImage(UIImage(named: "Bolinha-5"), for: .normal)
        }
        else {
            buttonPressed = true
            button1.setImage(UIImage(named: "Bolinha-4"), for: .normal)
        }
      
            

        
    }
    
    @IBOutlet weak var button2: UIButton!
    @IBAction func buttonAction2(_ sender: UIButton) {
        if buttonPressed {
            
            buttonPressed = false
            button2.setImage(UIImage(named: "Bolinha-5"), for: .normal)
        }
        else {
            buttonPressed = true
            button2.setImage(UIImage(named: "Bolinha-4"), for: .normal)
        }
        
    }

    @IBOutlet weak var button3: UIButton!
    @IBAction func buttonAction3(_ sender: UIButton) {
        if buttonPressed {
            
            buttonPressed = false
            button3.setImage(UIImage(named: "Bolinha-2"), for: .normal)
        }
        else {
            buttonPressed = true
            button3.setImage(UIImage(named: "Bolinha-4"), for: .normal)
        }
        
    }
    
    

    
    @IBOutlet weak var button4: UIButton!
    @IBAction func buttonAction4(_ sender: UIButton) {
        if buttonPressed {
            
            buttonPressed = false
            button4.setImage(UIImage(named: "Bolinha-3"), for: .normal)
        }
        else {
            buttonPressed = true
            button4.setImage(UIImage(named: "Bolinha-4"), for: .normal)
        }
        
    }
   
    
    @IBOutlet weak var button5: UIButton!
    @IBAction func buttonAction5(_ sender: UIButton) {
        if buttonPressed {
            
            buttonPressed = false
            button5.setImage(UIImage(named: "Bolinha-3"), for: .normal)
        }
        else {
            buttonPressed = true
            button5.setImage(UIImage(named: "Bolinha-4"), for: .normal)
        }
        
    }
}

Solution

  • What you are going to accomplish is called Radio Buttons, unfortunately iOS (unlike macOS) doesn't provide this functionality.

    My suggestion takes advantage of the option to assign different images to different states in Interface Builder – in this case the Default and Selected state – and to create an outlet collection, an array representing a sequence of UI elements of the same type.

    The suggestion doesn't support an empty selection, by default the first button is selected.


    • In ViewController

      • create an outlet collection

        @IBOutlet var buttons : [UIButton]!
        
      • and one IBAction

         @IBAction func buttonAction(_ sender: UIButton) { }
        
    • In Interface Buider

      • set the images to the Default and Selected states of each button in the Attribute Inspector.
      • connect the buttons in the proper order to the outlet collection.
      • assign the tags 0 to 4 to the buttons in the same order.
      • connect all buttons also to the (same) IBAction.
    • In ViewController

      • create a property for the tag of the currently selected button

         var selectedButton = 0
        
      • in viewDidLoad select the first button

         override func viewDidLoad() {
             super.viewDidLoad()
             buttons[selectedButton].isSelected = true
         }
        
      • Complete the IBAction, it deselects the previous button and selects the current.

         @IBAction func buttonAction(_ sender: UIButton) {
             let tag = sender.tag
             buttons[selectedButton].isSelected = false
             buttons[tag].isSelected = true
             selectedButton = tag
         }