[英]How does the view redraw itself when I disable/enable a button?
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. 我已经在
layoutSubviews
上放置了一个断点,但看不到它到达那里。 Nor it reaches us to the viewController's viewWillLayoutSubviews
. 它也没有到达viewController的
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. 我自己对此感到很好奇,因此我创建了一个简单的
UIButton
子类,并在一些重写的方法上设置了断点。 Here are my findings: 这是我的发现:
setEnabled:
on a UIButton
subclass instance which I called MyButton
in viewDidLoad
UIButton
子类实例上调用setEnabled:
UIButton
我在viewDidLoad
中将其称为MyButton
This triggered a call to setNeedsDisplay
method. 这触发了对
setNeedsDisplay
方法的调用。 It was called internally by the setEnabled
method of the UIButton
class. 它是由
UIButton
类的setEnabled
方法在内部调用的。 As you can see from the stack trace in this screenshot: 从该屏幕快照的堆栈跟踪中可以看到:
After setNeedsDisplay
, the setNeedsLayout
method was triggered. setNeedsDisplay
之后,将触发setNeedsLayout
方法。 The stack trace was similar to the earlier call: 堆栈跟踪类似于先前的调用:
After this the following methods were called in this order: layoutSubviews
, drawLayer:inContext:
, drawRect:
之后,
drawLayer:inContext:
以下顺序调用以下方法: layoutSubviews
, drawLayer:inContext:
, drawRect:
According to Apple's documentation of the UIView
class, 根据Apple的
UIView
类文档 ,
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.
您可以通过调用视图的setNeedsDisplay()或setNeedsDisplay(_ :)方法来实现。 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
: 这是关于
UIControl
的enabled
布尔值的文档:
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.
将此属性的值设置为YES可启用控件,而将NO禁用即可。 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;
将此属性设置为NO会将UIControlStateDisabled标志添加到控件的状态位掩码中。 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. 他们还提到控件的
state
位掩码已更新。 So, I believe, internally Apple's UIButton
class calls the setNeedsDisplay
method, which in-turn forces to re-draw itself. 因此,我相信,Apple的
UIButton
类在内部调用setNeedsDisplay
方法,从而强制重新绘制自身。 Based on the (UIControlState) state
property, the button draws itself respectively. 基于
(UIControlState) state
属性,按钮分别进行绘制。 You can find more on UIButton drawing here (look at Table 2 Appearance attributes) and UIView drawing here . 您可以在此处找到有关UIButton绘图的更多信息(请参见表2的外观属性) ,并在此处找到 UIView绘图的更多信息 。
But it probably won't trigger any events on the UIViewController
's view which has the button as a subview. 但是它可能不会在以按钮为子视图的
UIViewController
的视图上触发任何事件。 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. 但是,如果您想在视图控制器或按钮的超级视图中侦听对该属性的更改,则可以使用KVO并观察已
enabled
属性。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.