Highlight Button

I want to make a UIButton so that when its tapped the button becomes highlighted. However, I don't know what code to write for this. What I have done so far is just make a new swift file.

Accepted Reply

I think the best way to do it is to use segmented control.


- Declare a var in the viewController to track selected button

var selectedButton = 0

- Set tags 1, 2, 3 for your buttons, in IB

- You could create an array to hold the buttons, I will not show here, for simplicity sake

- You will probably set this var when you prepare to segue to the view

- Write a func to handle the hilite : hilite the selected, unhilite the others


func hiliteButtons() {

    if button1.tag == selectedButton {
        button1.backgroundColor = .red
    } else {
        button1.backgroundColor = .clear
    }

// Repeat for the 2 other buttons
}



Call this func in each IBAction after setting selectedButton to sender.tag

Replies

Our discussion goes nowhere if you do not answer questions, precisely.


1. What is the result of

print("selectedButton", selectedButton)

print("therapistGenderMale.tag", therapistGenderMale.tag) // Idem for all others


Have you defined IBAction for the button ?

Can you show the code of the IBAction associated to the buttons (if any) ?


Have you checked that the connection of the buttons to their IBOutlet are valid ?


Could you post the crashlog (with the sigabrt message)


==> PLEASE answer those questions


2. I still don't understand how to make an array

Do you mean an array of UIButton ?

Did you follow the steps ?

To create an array of UIButton:

- create a button in IB

- control-drag to viewController, and select Outlet collection

- you get this declaration:

@IBOutlet var allButtons: [UIButton]!

- create a second button in IB

- control-drag from the IBOutlet declaration to this new button, it will be included in Outlet collection ([UIButton]


==> WHERE exactly do you have problem ?


3. what you mean when you say you will probably set this var when you prepare to segue to the view

The buttons are in a controller (let call it destVC)

You go there from initilalVC

What you want, is that a button in destVC is preselected when you show destVC


==> IS THAT what you want ?


If so, when you segue, you need to tell destVC which button to hilite ; hence, you need to pass a parameter with selectedButton.


4. To do this, you have to:

- know which is preselectedButton ; this is done in initialVC. You store this value in thePreselectedButton

- How it is done, depends on your app ; on which condition do you choose the preselected button ? As you don't show code, it is hard to say

- Probably, you should have code as:

if someCondition {
    thePreselectedButton = 1
} else if someOtherCondition {
    thePreselectedButton = 2
} else if yetAnotherCondition {
      thePreselectedButton = 3
} else {
     thePreselectedButton = 0     // No preselection
}

- in prepare, you write

destVC.selectedButton = thePreselectedButton

- in destVC, you have define a var (selectedButton) to receive the value

var selectedButton = 0

- in destVC, in viewDidLoad, you use the value to set the hilite of the selectedButton, by calling hiliteButtons()

var selectedButtons = 0
    @IBOutlet var therapistGender: [UIButton]!
    @IBOutlet weak var therapistGenderFemale: UIButton!
    @IBOutlet weak var eitherGender: UIButton!
    @IBOutlet weak var therapistGenderMale: UIButton!

//MARK: Highlight Button Therapist Gender
    
    func hiliteButtons() {
        
        therapistGenderMale.backgroundColor = .white
        eitherGender.backgroundColor = .white
        therapistGenderFemale.backgroundColor = .white
        switch selectedButtons {
        case therapistGenderMale.tag :
            therapistGenderMale.backgroundColor = .lightGray
        case eitherGender.tag :
            eitherGender.backgroundColor = .lightGray
        case therapistGenderFemale.tag :
            therapistGenderFemale.backgroundColor = .lightGray
        default: break
        }
    }
    
    @IBAction func femaleTherapist(_ sender: Any) {
        print("selectedButtons", selectedButtons)
        print("therapistGenderFemale.tag", therapistGenderFemale.tag)
    }
    
    @IBAction func eitherTherapist(_ sender: Any) {
        print("selectedButtons", selectedButtons)
        print("eitherGender.tag", eitherGender.tag)
    }
    
    @IBAction func maleTherapist(_ sender: Any) {
        print("selectedButtons", selectedButtons)
        print("therapistGenderMale.tag", therapistGenderMale.tag)
    }

Heres is my code I was able to get rid of the crash error. However, the when I press the button it doesn't stay highlighted.

How did you solve the crash ? Was it bad connections to IBOutlets ?


You say: when I press the button it doesn't stay highlighted.

do you mean such as therapistGenderFemale ?

What do you get printed ?


Nothing happens as you have not set selectedButtons nor calle hilite


Complement as follows


   @IBAction func femaleTherapist(_ sender: Any) {
        selectedButtons = therapistGenderFemale.tag
        print("selectedButtons", selectedButtons)
        print("therapistGenderFemale.tag", therapistGenderFemale.tag)
        hiliteButtons()
    }


Do the same for other IBActions.


Nota

Looks like you do not use therapistGender anywhere ?

It works the female and male work and highlights like they are supposed too, but when I tapped the either button it highlights the male button, it doesn't highlight the either button. Here is the code


//MARK: Highlight Button Therapist Gender
    
    func hiliteButtons() {
        
        therapistGenderMale.backgroundColor = .white
        eitherGender.backgroundColor = .white
        therapistGenderFemale.backgroundColor = .white
        switch selectedButtons {
        case therapistGenderMale.tag :
            therapistGenderMale.backgroundColor = .lightGray
        case eitherGender.tag :
            eitherGender.backgroundColor = .lightGray
        case therapistGenderFemale.tag :
            therapistGenderFemale.backgroundColor = .lightGray
        default: break
        }
    }
    
    @IBAction func femaleTherapist(_ sender: Any) {
        selectedButtons = therapistGenderFemale.tag
        print("selectedButtons", selectedButtons)
        print("therapistGenderFemale.tag", therapistGenderFemale.tag)
        hiliteButtons()
    }
    
    @IBAction func eitherTherapist(_ sender: Any) {
        selectedButtons = eitherGender.tag
        print("selectedButtons", selectedButtons)
        print("eitherGender.tag", eitherGender.tag)
        hiliteButtons()
    }
    
    @IBAction func maleTherapist(_ sender: Any) {
        selectedButtons = therapistGenderMale.tag
        print("selectedButtons", selectedButtons)
        print("therapistGenderMale.tag", therapistGenderMale.tag)
        hiliteButtons()
    }

Are you sure you have set different tags for all buttons ?


I would suspect you have given the same tag to eitherGender and to therapistGenderMale

No, I just checked the tags are set at 1, 2, and 3. In the box on the bottom of XCode, it reads this when I tap the either button.

selectedButtons 2

eitherGender.tag 2

selectedButtons 3

therapistGenderMale.tag 3

You have probably ill connected the eitherGender button.


Look at its connections (connection inspector): it is probably connected to 2 IBActions : eitherTherapist and maleTherapist

Delecte the second one.


Note : check also connections of other buttons, in case.

It works now thank you. I just have one more question I want it so that the either button is already preselected. Then if you decide to switch to the male or female button the highlight changes to that button how would I do that.

That's very easy


in prepare for segue, you write :


     thePreselectedButton = 2 // THis is the eitherGender.tag 
     destVC.selectedButton = thePreselectedButton
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        eitherGender.tag = 2 
        destVC.selectedButton = eitherGender
    }
  

This is the code that I wrote, however, I don't think I did this right. I get an error saying unresolved identifier for destVC

I am still getting an error when I try to implement this code.


override func prepare(for segue: UIStoryboardSegue, sender: Any?) {  
        eitherGender.tag = 2   
        destVC.selectedButton = eitherGender  
    }


Also, where am I supposed to implement this code? This is the code I have for highlighting the buttons:


    func hiliteButtons1() {
        
        driverGenderMale.backgroundColor = .white
        eitherGender.backgroundColor = .white
        driverGenderFemale.backgroundColor = .white
        switch selectedButtons {
        case driverGenderMale.tag :
            driverGenderMale.backgroundColor = UIColor.customBlue
        case eitherGender.tag :
            eitherGender.backgroundColor = UIColor.customBlue
        case driverGenderFemale.tag :
            driverGenderFemale.backgroundColor = UIColor.customBlue
        default: break
        }
    }
    
    @IBAction func femaleDriver(_ sender: Any) {
        selectedButtons = driverGenderFemale.tag
        print("selectedButtons", selectedButtons)
        print("driverGenderFemale.tag", driverGenderFemale.tag)
        hiliteButtons1()
    }
    
    @IBAction func eitherDriver(_ sender: Any) {
        selectedButtons = eitherGender.tag
        print("selectedButtons", selectedButtons)
        print("eitherGender.tag", eitherGender.tag)
        hiliteButtons1()
    }
    
    @IBAction func maleDriver(_ sender: Any) {
        selectedButtons = driverGenderMale.tag
        print("selectedButtons", selectedButtons)
        print("driverGenderMale.tag", driverGenderMale.tag)
        hiliteButtons1()
    }