If I enable/disable a button…what method would get called on the view?
I’ve already placed a breakpoint on the layoutSubviews
and don’t see it reaching there. Nor it reaches us to the viewController's viewWillLayoutSubviews
. So I'm just curious to know how it works and what method it triggers
That's a good question. I got curious about this myself, so I created a simple UIButton
subclass and put breakpoints on a few overridden methods. Here are my findings:
setEnabled:
on a UIButton
subclass instance which I called MyButton
in viewDidLoad
This triggered a call to setNeedsDisplay
method. It was called internally by the setEnabled
method of the UIButton
class. As you can see from the stack trace in this screenshot:
After setNeedsDisplay
, the setNeedsLayout
method was triggered. The stack trace was similar to the earlier call:
After this the following methods were called in this order: layoutSubviews
, drawLayer:inContext:
, drawRect:
According to Apple's documentation of the UIView
class,
When the actual content of your view changes, it is your responsibility to notify the system that your view needs to be redrawn. You do this by calling your view’s setNeedsDisplay() or setNeedsDisplay(_:) method of the view. These methods let the system know that it should update the view during the next drawing cycle. Because it waits until the next drawing cycle to update the view, you can call these methods on multiple views to update them at the same time.
And here is the documentation on the enabled
boolean of UIControl
:
A Boolean value indicating whether the control is enabled. Set the value of this property to YES to enable the control or NO to disable it. An enabled control is capable of responding to user interactions, whereas a disabled control ignores touch events and may draw itself differently. Setting this property to NO adds the UIControlStateDisabled flag to the control’s state bitmask; enabling the control again removes that flag.
They mention that a disabled control may re-draw itself differently. They also mention the control's state
bitmask is updated. So, I believe, internally Apple's UIButton
class calls the setNeedsDisplay
method, which in-turn forces to re-draw itself. Based on the (UIControlState) state
property, the button draws itself respectively. You can find more on UIButton drawing here (look at Table 2
Appearance attributes) and UIView drawing here.
But it probably won't trigger any events on the UIViewController
's view which has the button as a subview. Although, you could use KVO and observe the enabled
property if you want to listen to changes to the property in your view controller or in the button's superview.