4

I want to display 2 strings (at different positions in the button) with different fonts and colors (I'm using the button's setTitle for one, and I need another one), and some attributes must be changed based on the current UIControlState (like the color).

So, I'm searching the best way to add a second label to a UIButton. I need the label to be configurable per UIControlState (I want a different color for UIControlStateNormal and UIControleStateHighlighted for example).

I've tried the following approches:

  • Subclass a UIButton and use drawRect: while not recommended (and I now understand why), I don't think it's even possible, it looks like the button's drawRect method is called (and after the one of my subclass) even if I don't call super.
  • Create a new UILabel and add it as a subview to my button: this is working quite well, except I don't know how to change the color when the UIControlState of the button is changing
  • Create a new layer and use drawLayer: I don't know how to get the drawLayer method to be called every time the button state is changing (my drawLayer only gets called once, when I use setNeedsDisplay just after adding my layer to the button)

Is there another way to achieve what I'm trying to do, or maybe one of those solutions might work (with a few tweaks)?

Thanks!

Monolo
  • 18,205
  • 17
  • 69
  • 103
Chris
  • 136
  • 7

2 Answers2

2

The second of your approach works fine. Just add 2 targets: First update to "normal state" target using "all touch events". Second update to "highlighted" using "touch down" event.

If the states are not only changed by touches and want to handle this more generally, Id suggest multithreading. All you really need is calling performSelectorInBackground when initializing all this elements (the selector updates label according to button state) and then again call same performSelectorInBackground on the end of "update label" method, creating an infinite loop.

Matic Oblak
  • 16,318
  • 3
  • 24
  • 43
  • Seems a little complicated for the simple thing I'm trying to do, but I suppose it's because UIButton is a class that cannot be easily subclassed. I'll take a look at that solution if nothing else comes out. – Chris Dec 09 '11 at 14:57
2

Ok, I think I found a working solution (for my problem at least).

I'm subclassing the UIButton class (it works for me, since I'm using a custom drawn button anyway), and I override the titleRectForContentRect method that gets called everytime the title has to be displayed (including after a state change, just before display).

I added an UILabel to the button's view to display the second string I want, and during the titleRectForContentRect, I compute the correct frame location for my label, I update my label's text font and color based on the button's state (self.state), and that's all I need.

Chris
  • 136
  • 7