为啥不调用draw(_ layer: CALayer, in ctx: CGContext) 没有空draw(_ rect: CGRect)?

Posted

技术标签:

【中文标题】为啥不调用draw(_ layer: CALayer, in ctx: CGContext) 没有空draw(_ rect: CGRect)?【英文标题】:Why draw(_ layer: CALayer, in ctx: CGContext) is not called without empty draw(_ rect: CGRect)?为什么不调用draw(_ layer: CALayer, in ctx: CGContext) 没有空draw(_ rect: CGRect)? 【发布时间】:2020-09-01 13:15:44 【问题描述】:

当我覆盖 draw(_ rect: CGRect) 并将其留空时,就会调用 draw(_ layer: CALayer, in ctx: CGContext)。并且画了圆圈。

这里是代码。我刚刚分配 SpecialView 类在 IB 中查看。

class SpecialView : UIView 
   override func draw(_ rect: CGRect) 
   
  
   override func draw(_ layer: CALayer, in ctx: CGContext) 
            UIGraphicsPushContext(ctx)
            let p = UIBezierPath(ovalIn: CGRect(0,0,100,100))
            UIColor.blue.setFill()
            p.fill()
            UIGraphicsPopContext()
   


但是当我不覆盖 draw(_ rect: CGRect) 时,只需在代码 sn-p 中保留如下代码:

 class SpecialView : UIView 
 
   override func draw(_ layer: CALayer, in ctx: CGContext) 
            UIGraphicsPushContext(ctx)
            let p = UIBezierPath(ovalIn: CGRect(0,0,100,100))
            UIColor.blue.setFill()
            p.fill()
            UIGraphicsPopContext()
   

draw(_ layer: CALayer, in ctx: CGContext) 函数没有被调用。圆圈没有画出来。

你知道为什么吗?

【问题讨论】:

我觉得我以前在某个地方看过这段代码…… @matt 当然,在你的书中!非常感谢! :) 我们不要把问题变成广告;那是错误的。 @matt 好的,但很抱歉我确实说过我写了这段代码。 【参考方案1】:

图层对绘制非常懒惰。除非你告诉他们他们需要,否则他们不会画画。所以,你可以通过明确告诉层setNeedsDisplay来解决这里的问题。

但是,浏览量 更主动一些。它们在某些情况下会自动重绘自己,比如它们第一次出现时。由于该层是视图的底层,因此如果您可以让视图自动重绘自身,则可以让该层参与自动重绘。

但是(这是重要的部分)运行时,为了效率,假设如果视图有 no drawRect 实现,则不需要自动重绘。

这就是你的答案:

    通常,除非您告诉图层,否则图层根本不会重绘。

    通过提供drawRect 实现,即使它是空的,您也可以告诉视图 在需要时自动重绘自己。

    这是视图的底层,所以它与视图一起重绘。

【讨论】:

所有这些信息在您从中获得示例的书中。你可能只是读得还不够远。六个蓝色圆圈的例子在第 2 章,但是图层绘制直到第 3 章才解释。 感谢您的帮助!现在情况对我来说更清楚了! @Ninja 第 3 章的关键语句是:“如果一个层是视图的底层,……你可能无论如何都想实现 draw(_:),让那个实现为空。原因是这会导致该层在适当的时刻重新显示自身.... ,你应该实现draw(_:) 什么都不做。” @matt 我们也可以将contentMode 设置为.redraw,而不是覆盖drawRect。这样做有什么问题吗?

以上是关于为啥不调用draw(_ layer: CALayer, in ctx: CGContext) 没有空draw(_ rect: CGRect)?的主要内容,如果未能解决你的问题,请参考以下文章

为啥我的窗口不适用于 on_draw?

iOS 自定义layer的两种方式

setNeedsDisplay() 没有调用 draw(_ rect: CGRect)

如何从 cellForRowAt 调用 draw(_ rect: CGRect) 在自定义 tableview 上绘图?

为啥 OpenGL 告诉我我已经使用了 GL_STATIC_DRAW 而我已经指定了其他方式?

layer.alert弹出层后,跳转页面,为啥弹出层只是闪一下