How to add a second UILabel to a UIButton, customizable for each UIControlState

I want to display 2 lines (in different positions of the button) with different fonts and colors (I use the setTitle button for one, and I need another), and some attributes should be changed based on the current UIControlState (e.g. color).

So I'm looking for a better way to add a second shortcut to UIButton . I need the label to be set to UIControlState (for example, I want a different color for UIControlStateNormal and UIControleStateHighlighted ).

I tried the following statements:

  • Subclass a UIButton and use drawRect : not recommended yet (and now I understand why), I don’t think it is possible, it seems like the drawRect method (and after it my subclass) is being called, even if I don't call super.
  • Create a new UILabel and add it as a subview to my button: this works very well, except that I don’t know how to change the color when the UIControlState button button changes
  • Create a new layer and use drawLayer : I don’t know how to make the drawLayer method drawLayer called every time the button state changes (my drawLayer only drawLayer called once when I use setNeedsDisplay right after adding my layer to the button)

Is there any other way to achieve what I'm trying to do, or maybe one of these solutions might work (with multiple settings)?

Thanks!

+4
source share
2 answers

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

I subclass the UIButton class (it works for me, since I use a custom back button anyway), and I override the titleRectForContentRect method, which is called every time the title should be displayed (including after a state change, just before the display).

I added UILabel to the button view to display the second line I want, and during titleRectForContentRect , I calculate the correct frame position for my label, I update the text font and text color based on the state of the button ( self.state ) and all that I need.

+2
source

The second of your approaches works just fine. Just add 2 goals: first update the “normal state” goal using “all touch events”. The second update for is highlighted using the touch down event.

If the states are not only altered by touches and want to handle it more generally, Id offers multithreading. All you really need is to call the performSelectorInBackground function when all of these elements are initialized (selector update label according to the state of the button), and then call the same SelectorInBackground function again at the end of the "label label" method, creating an endless loop.

+2
source

Source: https://habr.com/ru/post/1385507/


All Articles