3

I wonder how I get my border around my UIButton to change opacity together with the text inside it, when it is either clicked or highlighted.

My logic tells me, that it should be something like this.. but it doesn't seem to work:

    //BTN STYLING

    btnstd.layer.cornerRadius = 5
    btnstd.layer.borderWidth = 1.5
    btnstd.layer.borderColor = UIColor.white.cgColor

    //Change bordercolor when highlighted
    if(btnstd.isHighlighted) {
    btnstd.layer.borderColor = UIColor(white:1,alpha:0.3).cgColor
    }

This is by the way put inside my ViewDidLoad() function

Jeppe Christensen
  • 1,680
  • 2
  • 21
  • 50

2 Answers2

7

The actions you are looking for are .touchDown and anything .touchUp:

override func viewDidLoad() {
    super.viewDidLoad()
    theButton.setTitle("Normal", for: .normal)
    theButton.setTitle("Highlighted", for: .highlighted)
    theButton.layer.borderColor = UIColor.red.cgColor
    theButton.layer.borderWidth = 1
    theButton.addTarget(self, action: #selector(startHighlight), for: .touchDown)
    theButton.addTarget(self, action: #selector(stopHighlight), for: .touchUpInside)
    theButton.addTarget(self, action: #selector(stopHighlight), for: .touchUpOutside)
}
func startHighlight(sender: UIButton) {
    theButton.layer.borderColor = UIColor.green.cgColor
    theButton.layer.borderWidth = 1
}
func stopHighlight(sender: UIButton) {
    theButton.layer.borderColor = UIColor.red.cgColor
    theButton.layer.borderWidth = 1
}
Nimantha
  • 6,405
  • 6
  • 28
  • 69
  • 1
    Thats awesome mate!! btnstd.addTarget(self, action: #selector(stopHighlight), for: .touchDragOutside) I added this to my actions. Now the only thing that makes it different though, is how the standard button fades in / out. – Jeppe Christensen Oct 27 '16 at 16:05
  • I'm guessing that's OS related. There's another question in the last day about how a tap in the bottom left of the screen takes longer to process. My thinking (on that) is is takes some time for the OS to decide if it's a tap, versus double tap, versus long press, etc. In your case I'm thinking it's something similar - your added .touchDragOutside and maybe it's the OS deciding for itself what you are trying to do. Most users simply "tap and release" but everything has to be covered. –  Oct 27 '16 at 17:48
  • Thats a good point. However, i figured that there should, or must be some setting within the xib (not sure what its called) for the button text in which the "transition" on press, drag is determined. - i call it transition, because i do web mostly – Jeppe Christensen Oct 27 '16 at 19:49
0

It depends on what you are trying to do.

Case #1: You want this change to happen when the button is highlighted, but in a normal state have a different set of properties.

let theButton = UIButton()
// set common properties and layout code
theButton.setTitle("Normal", for: .normal)
theButton.setTitle("Highlighted", for: .highlighted)

In addition, you have setTitleColor(), setAttributedTitle, setTitleShadowColor(), setImage(), and setBackgroundImage() that you can code directly.

Border color in this case would need a subclass (not an extension, you want public properties) where you will check self.layer.hitTest() after wiring up a tap gesture on self.

Case #2: You want the button state to change when clicked, and stay changed.

You are part way there. If you supply the button in IB, make sure you add an IBAction for event touchUpInside. If you are working in code, here's the Swift 3 syntax.

theButton.addTarget(self, action: #selector(changeButton), for: .touchUpInside)

func changeButton(sender: UIButton) {
    sender.setTitle("New Title", for: .normal)
    sender.layer.borderColor = UIColor.red.cgColor
}

My preference (but only that) is to more strongly-type the sender (I think that's the correct term) for my actions. I'm sure there are pros and cons for using a specific sender (like UIButton) over AnyObject, but in this case I think the biggest reason is you don't need to force-cast the sender to UIButton.

  • Thank you for your reply. Remember that the selector in swift 3 is now #selector(classname.funcname) However, what i wanted to achieve, is for the border to do the same color opacity "pulse" that the text inside my button does, when i press it. if you catch my drift? - sorry for my late reply, had to go to bed yesterday. – Jeppe Christensen Oct 27 '16 at 13:23
  • Yes, its classname.funcname - my skeleton code had a shortcut in that the funcname was in the same class! See if my new answer helps you. –  Oct 27 '16 at 15:50