0

I need to change the Image of a UIButton in my NAV bar when a user taps it 3 times. Each tap displays a different UIImage and its corresponding collection view. I got the animated collection view working perfectly, but...

How do I get the button images to change in Swift?

I've tried multiple methods and can't seem to get it to work, for example:

@IBAction func buttonTapped(sender: UIButton) {

    if let myButton = UIImage(named:"btn1") {
        sender.setImage(myButton, forState: .Normal)
    }
    if let myButton = UIImage(named:"btn2") {
        sender.setImage(myButton, forState: .Normal)
    }
    if let myButton = UIImage(named:"btn3") {
        sender.setImage(myButton, forState: .Normal)
    }
}

There are lots of posts relating to changing a uibutton for two states, e.g., stopwatch or play/pause, but I need 3 states in a navigation bar.

Thanks!

mvien
  • 237
  • 4
  • 12

1 Answers1

0

I think there are two easy ways to do this:

  1. You can set a variable Int in your class and just count it up until it is 2 and then set it again to 0 like this:

      var buttonCounter: Int = 0
    
    @IBAction func buttonTapped(sender: UIButton) {
    
    if buttonCounter == 0{
        let myButton = UIImage(named:"btn1")
        sender.setImage(myButton, forState: .Normal)
        buttonCounter++
    }
    else if buttonCounter == 1 {
        let myButton = UIImage(named:"btn2")
        sender.setImage(myButton, forState: .Normal)
        buttonCounter++
    }
    else {
        let myButton = UIImage(named:"btn3")
        sender.setImage(myButton, forState: .Normal)
        buttonCounter = 0
      }
    }
    
  2. You could do nearly the same but instead of using a variable you can use the .tag attribute of the UIButton. The tag is an integer and is normally used to find out which button calls the IBAction but you have only one button calling the function so you can use it like this:

    @IBAction func buttonTapped(sender: UIButton) {
    
    if sender.tag == 0{
        let myButton = UIImage(named:"btn1")
        sender.setImage(myButton, forState: .Normal)
        sender.tag++
    }
    else if sender.tag == 1 {
        let myButton = UIImage(named:"btn2")
        sender.setImage(myButton, forState: .Normal)
        sender.tag++
    }
    else {
        let myButton = UIImage(named:"btn3")
        sender.setImage(myButton, forState: .Normal)
        sender.tag = 0
    }
    }
    
M. Kremer
  • 679
  • 6
  • 24
  • Thanks M. Looks good. Having difficulty getting it to work. Not sure if it's because the button is in nav bar? Error is "[UIBarButtonItem setImage:forState:]: unrecognized selector sent to instance" – mvien Aug 31 '15 at 20:34
  • Look at http://stackoverflow.com/questions/2455161/unrecognized-selector-sent-to-instance for some help – M. Kremer Aug 31 '15 at 20:46
  • That link is a total hodgepodge. ;) Not much help, though I did try to check NSWindow memory mgmt, rewired event handlers (outlet and action), removed button's target action, checked classes in SB, and triple checked for typos. I think it's because it's a bar button item and UIBarButtonItem does not inherit from UIButton, so setImage:forState will not work as proposed. – mvien Aug 31 '15 at 21:21
  • I'm not sure but could it be that you set up an outlet, deleted it and then forget to disconnect it at the view controller? – M. Kremer Sep 01 '15 at 07:40
  • I got it to work. All I did differently was added UIControlState to .Normal. Thanks! – mvien Sep 09 '15 at 12:00