35

So I have a storyboard with 3 buttons I want to just create 1 action for all those 3 buttons and decide what to do based on their label/id...

Is there a way to get some kind of identifier for each button?

By the way they are images, so they don't have a title.

@IBAction func mainButton(sender: UIButton) {
    println(sender)
}
matt
  • 2,312
  • 5
  • 34
  • 57

16 Answers16

35

You can set a tag in the storyboard for each of the buttons. Then you can identify them this way:

@IBAction func mainButton(sender: UIButton) {
    println(sender.tag)
}

EDIT: For more readability you can define an enum with values that correspond to the selected tag. So if you set tags like 0, 1, 2 for your buttons, above your class declaration you can do something like this:

enum SelectedButtonTag: Int {
    case First
    case Second
    case Third
}

And then instead of handling hardcoded values you will have:

@IBAction func mainButton(sender: UIButton) {
    switch sender.tag {
        case SelectedButtonTag.First.rawValue:
            println("do something when first button is tapped")
        case SelectedButtonTag.Second.rawValue:
            println("do something when second button is tapped")
        case SelectedButtonTag.Third.rawValue:                       
            println("do something when third button is tapped")
        default:
            println("default")
    }
}
Vasil Garov
  • 4,851
  • 1
  • 26
  • 37
19

If you want to create 3 buttons with single method then you can do this by following code...Try this

Swift 3
Example :-

override func viewDidLoad()
{
    super.viewDidLoad()
    Button1.tag=1
    Button1.addTarget(self,action:#selector(buttonClicked),
                      for:.touchUpInside)
    Button2.tag=2
    Button2.addTarget(self,action:#selector(buttonClicked),
                      for:.touchUpInside)
    Button3.tag=3
    Button3.addTarget(self,action:#selector(buttonClicked),
                      for:.touchUpInside)

}

func buttonClicked(sender:UIButton)
{
    switch sender.tag
    {
        case 1: print("1")     //when Button1 is clicked...
            break
        case 2: print("2")     //when Button2 is clicked...
            break
        case 3: print("3")     //when Button3 is clicked...
            break
        default: print("Other...")
    }
}
Pragnesh Vitthani
  • 2,532
  • 20
  • 28
9

You can create an outlet for your buttons and then implement:

@IBAction func mainButton(sender: UIButton) {
    switch sender {
    case yourbuttonname:
        // do something
    case anotherbuttonname:
        // do something else
    default: println(sender)
    }
}
Allan Chau
  • 693
  • 1
  • 5
  • 15
  • While using the sender tag property works, IMHO this is the simplest solution and the easiest to manage since you don't have to keep track of which tag belongs to which button (or other object) in storyboard. – B-Rad May 29 '19 at 21:23
7

Swift 4 - 5.1

@IBAction func buttonPressed(_ sender: UIButton) {
        if sender.tag == 1 {
            print("Button 1 is pressed")
        }
}
Community
  • 1
  • 1
Jonas Deichelmann
  • 3,513
  • 1
  • 30
  • 45
5

You have to set tag value to what you need and access it with

sender.tag
Nerkyator
  • 3,976
  • 1
  • 25
  • 31
5

Assuming you gave them all proper names as @IBOutlets:

@IBOutlet var weak buttonOne: UIButton!
@IBOutlet var weak buttonTwo: UIButton!
@IBOutlet var weak buttonThree: UIButton!

You can use the following to determine which is which

@IBAction func didPressButton(sender: AnyObject){
 // no harm in doing some sort of checking on the sender
 if(sender.isKindOfClass(UIButton)){

    switch(sender){
    case buttonOne:    
                   //buttonOne action  
                   break
    case buttonTwo:   
                  //buttonTwo action  
                   break
    case buttonThree: 
                  //buttonThree action  
                   break
    default:
                   break
    }
}
Rachel Fong
  • 730
  • 1
  • 8
  • 16
5

Swift 3 Code: In xcode Please set tag for each button first to work following code.

@IBAction func threeButtonsAction(_ sender: UIButton) {

        switch sender.tag {
        case 1:
            print("do something when first button is tapped")
            break
        case 2:
            print("do something when second button is tapped")
            break
        case 3:
            print("do something when third button is tapped")
            break
        default:
            break
        }
    }
mriaz0011
  • 1,887
  • 23
  • 11
4

You can do like this, just you have to give tag to all the buttons and do like this:

@IBAction func mainButton(sender: AnyObject)
    {
        switch sender.tag {
        case 1:
            println("do something when first button is tapped")
        case 2:
            println("do something when second button is tapped")
        case 3:
            println("do something when third button is tapped")

        default:
            println("default")
        }

    }
3

Swift 4

add tag on button

let button = UIButton()
button.tag = 10

click event

@IBAction func mainButton(sender: UIButton) {
    switch sender.tag {
   
    case 10:
        print("10")
    case 11:
        print("11")
  
    default:
         print("yes")
    }
}
Nimantha
  • 6,405
  • 6
  • 28
  • 69
Dinithe Pieris
  • 1,822
  • 3
  • 32
  • 44
3

Use the outlets instead, tags clutter the code and make the readability way worse. Think about the poor developer that reads the code next and sees if sender.tag = 381 { // do some magic }, it just won't make any sense.

My example:

class PhoneNumberCell: UITableViewCell {
  @IBOutlet weak var callButton: UIButton!
  @IBOutlet weak var messageButton: UIButton!

  @IBAction func didSelectAction(_ sender: UIButton) {
    if sender == callButton {
      debugPrint("Call person")
    } else if sender == messageButton {
      debugPrint("Message person")
    }
  }

  [...]
}

You could also do this in a nice switch as well, which would make it even better.

Tested on Swift 5.1

Paul Peelen
  • 10,073
  • 15
  • 85
  • 168
1

In this case you can use NSObject extension Accessibility Element UIAccessibility.

I have used accessibilityLabel and accessibilityIdentifier both are success in call and condition checking.

First You can set a Accessibility Label or Identifier in the storyboard for each of the buttons in Identity inspector. Accessibility should be enabled.

enter image description here

To check/Identify button by

@IBAction func selectionPicker(_ sender: UIButton){
        if sender.accessibilityLabel == "childType"{ //Check by accessibilityLabel
            print("Child Type")
        }
        if sender.accessibilityIdentifier == "roomType"{ //Check by accessibilityIdentifier
            print("Room Type")
        }
        performSegue(withIdentifier: "selectionViewSegue", sender:sender)
    }

On Swift 3.2 and 4.0 with Xcode 9.0

Pranavan SP
  • 1,785
  • 1
  • 17
  • 33
1

Given the case you labeled your buttons "1", "2", "3":

@IBAction func mainButton(sender: UIButton) {
    switch sender.titleLabel?.text {
        case "1":
            print("do something when first button is tapped")
        case "2":
            print("do something when second button is tapped")
        case "3":
            print("do something when third button is tapped")
        default:
            () // empty statement or "do nothing"
    }
}
Ikem Krueger
  • 186
  • 1
  • 1
  • 12
1

Swift 5.5

I have utility methods in other classes that do not have an instance of my ViewController, so I don't compare the sent objects to what is defined in the ViewController's IBOutlets.

I don't use tags if I can use a plain language identifier on my UI objects. I'd rather have plain language identifiers than numbers to identify my objects because it is easier for me. Just another way of doing it.

If I need to use a utility method, I set it up with a sender parameter so I can send the button and then figure out which button was clicked based on the assigned identity of the button within Storyboard.

For example:

class Utility {

    func doSomething(sender: Any?) {
        guard let button = sender as? NSButton else {
            print("Unable to set button from sender.")
            return
        }
        guard case buttonID = button.identifier?.rawValue else {
            print("Unable to get button identifier.")
            return
        }
        switch buttonID {
            case: "firstButton":
                _ = buttonID // Perform firstButton action
            case: "secondButton":
                _ = buttonID // Perform secondButton action
            case: "thirdButton":
                _ = buttonID // Perform thirdButton action
            default:
                // shouldn't get here - error?
        }
    }

}

In my ViewController I have the following buttons set up as IBOutlets and their identity is the same in Storyboard.

@IBOutlet weak var firstButton: NSButton?
@IBOutlet weak var secondButton: NSButton?
@IBOutlet weak var thirdButton: NSButton?

Then I have my IBActions:

@IBAction func firstButtonClicked(sender: Any?) {
    utility.doSomething(sender: sender)
}

@IBAction func secondButtonClicked(sender: Any?) {
    utility.doSomething(sender: sender)
}

@IBAction func thirdButtonClicked(sender: Any?) {
    utility.doSomething(sender: sender)
}
SouthernYankee65
  • 1,129
  • 10
  • 22
0

In my case what i did, just like the answers above i used the tag to identify the specific button, what i added is that i added a UIButton extension that adds an id so that i can set a string id

i had three buttons with tags 0, 1 and 2

Then created the extension

extension UIButton {
    var id: String {
        let tag = self.tag

        switch tag {
            case 0:
                return "breakfast"

           case 1:
               return "lunch"

           case 2:
               return "dinner"

           default:

               return "None"
       }
    }
  }

When accessing a button in an IBAction i would just call:

sender.id
Paul Kahohi
  • 164
  • 1
  • 3
  • 6
0

Select your first button and give it tag 0, and select second button and give it tag 1 and so on, in action check the tag bit and perform you functionalities on the basis of tag bit.:
Select your first button and give it tag 0, and select second button and give it tag 1 and so on, in action check the tag bit and perform you functionalities on the basis of tag bit.

Zoe
  • 27,060
  • 21
  • 118
  • 148
-1
switch sender as! NSObject {
case self.buttoneOne:
    println("do something when first button is tapped")
case self.buttoneTwo:
    println("do something when second button is tapped")
default:
    println("default")
}
Nimantha
  • 6,405
  • 6
  • 28
  • 69
FlimFlam Vir
  • 1,080
  • 9
  • 15