【问题标题】: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 好的,但很抱歉我确实说过我写了这段代码。

标签: ios swift uikit core-graphics uigraphicscontext


【解决方案1】:

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

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

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

这就是你的答案:

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

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

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

【讨论】:

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