Reputation: 136
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:
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.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 changingdrawLayer
: 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!
Upvotes: 4
Views: 2234
Reputation: 136
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.
Upvotes: 2
Reputation: 16774
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.
Upvotes: 2