UIButton's setImage(_:for:) breaks "highlighted adjusts image"

My app has a lot of buttons that indicate their "on" state with a special image, assigned in Interface Builder to the Selected state. There's a different image assigned to the Default state, for "off."

I found that when the user tapped a button that was "on," iOS insisted on redrawing it with the Default image. It turns out that Interface Builder misrepresents button states as exclusive:

  • default
  • highlighted
  • selected
  • disabled

Wrong. For example, a button can be selected AND highlighted. That was the problem in my case, which you can solve programmatically by doing a union of states like this:

thirdsButton.setImage(UIImage(named: "frame_guide_3x3"), for: UIControl.State.selected.union(.highlighted))

That actually does work... but it breaks "highlighted adjusts image," where iOS will dim the button slightly on contact. Now the user doesn't get any feedback upon pressing the button.

Known defect?

UIButton's setImage(_:for:) breaks "highlighted adjusts image"
 
 
Q