当我禁用/启用按钮时,视图如何重绘?

时间:2018-04-23 15:25:48

标签: ios uiview autolayout drawing layoutsubviews

如果我启用/禁用按钮......视图会调用哪种方法?

我已经在layoutSubviews上放置了一个断点,但是没有看到它到达那里。它也没有到达viewController的viewWillLayoutSubviews。所以我很想知道它是如何工作的以及它触发的方法

1 个答案:

答案 0 :(得分:2)

这是一个很好的问题。我自己对此感到好奇,所以我创建了一个简单的UIButton子类,并在一些重写方法上添加了断点。以下是我的发现:

  1. 在我setEnabled:
  2. 中呼叫UIButton的{​​{1}}子类实例上调用了MyButton
  3. 这会触发对viewDidLoad方法的调用。它是由setNeedsDisplay类的setEnabled方法在内部调用的。正如您在此屏幕截图中的堆栈跟踪中所看到的那样:

    enter image description here

  4. UIButton之后,触发了setNeedsDisplay方法。堆栈跟踪与之前的调用类似:

    enter image description here

  5. 在此之后,按以下顺序调用以下方法:setNeedsLayoutlayoutSubviewsdrawLayer:inContext:

  6. 根据drawRect:类的Apple's documentation

      

    当视图的实际内容发生变化时,您有责任通知系统您的视图需要重新绘制。您可以通过调用视图的视图的setNeedsDisplay()或setNeedsDisplay(_ :)方法来完成此操作。这些方法让系统知道它应该在下一个绘图周期中更新视图。因为它会等到下一个绘图周期来更新视图,所以您可以在多个视图上调用这些方法来同时更新它们。

    这是关于UIView的{​​{1}}布尔值的文档:

      

    一个布尔值,指示控件是否已启用。   将此属性的值设置为YES以启用控件,或者将NO设置为禁用它。启用的控件能够响应用户交互,而禁用的控件会忽略触摸事件,并可能以不同的方式绘制自己。将此属性设置为NO会将UIControlStateDisabled标志添加到控件的状态位掩码;启用控件再次删除该标志。

    他们提到残疾人控制可能会以不同方式重新划分。他们还提到控件的enabled位掩码已更新。因此,我相信,Apple内部的UIControl课程调用了state方法,后者又强制重新绘制自己。基于UIButton属性,该按钮分别绘制自己。您可以在UIButton绘图here (look at Table 2 Appearance attributes)和UIView绘图here上找到更多信息。

    但它可能不会触发setNeedsDisplay视图中任何以按钮作为子视图的事件。虽然,如果您想在视图控制器或按钮的超级视图中收听对属性的更改,可以使用KVO并观察(UIControlState) state属性。