为啥不调用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)?的主要内容,如果未能解决你的问题,请参考以下文章
setNeedsDisplay() 没有调用 draw(_ rect: CGRect)
如何从 cellForRowAt 调用 draw(_ rect: CGRect) 在自定义 tableview 上绘图?