CALayer委托方法drawLayer没有被调用

Posted

技术标签:

【中文标题】CALayer委托方法drawLayer没有被调用【英文标题】:CALayer delegate method drawLayer not getting called 【发布时间】:2009-07-30 18:00:12 【问题描述】:

我的对象 NSObject 的子类具有 CALayer 实例变量。我用它来绘制和缓存内容,并将其委托设置为我的对象。

但由于某种原因,drawLayer:inContext: 方法永远不会被调用。而 actionForLayer:forKey: 委托方法确实被调用,这意味着委托在对象的 init 方法中使用 layer.delegate = self 正确设置。

关于阻止我的图层绘制方法drawLayer:inContext: 被调用的任何建议?

我经常被称为[layer setNeedDisplay]。所以我想这是一些基本错误。

【问题讨论】:

【参考方案1】:

drawLayer:inContext: 如果您的框架是 CGRectZero 或屏幕外,则不会被调用。此外,如果您的 CALayer 未附加到现有的屏幕图层,则无论您调用多少次setNeedsDisplay

,它都不会绘制

【讨论】:

【参考方案2】:

实现一个空的drawRect:

- (void)drawRect:(CGRect)rect 

取自 ZoomingPDFViewer 项目:-

UIView 使用-drawRect: 的存在来判断它是否应该 允许其 CALayer 无效,这将导致 层创建后备存储和-drawLayer:inContext: 叫。通过实现一个空的-drawRect: 方法,我们允许 UIKit 继续执行这个逻辑,同时做我们真正的绘图工作 在-drawLayer:inContext:内部

【讨论】:

在 macOS 上也是如此。 Apple 告诉开发人员不要在 UIView 中实现空的 drawRect 方法,因为它会影响性能。调用 -[setNeedsDisplay] 似乎是一个更好的解决方案。 (为我工作。)【参考方案3】:

必须调用图层对象的setNeedsDisplay。简单地将图层添加为子图层并不能为您做到这一点。这是从 Ray Wenderlich 的 CALayer tutorial 那里得到的。

【讨论】:

【参考方案4】:

如果您最终将 CALayer 与 UIView 一起使用,则委托必须是视图对象本身:

来自 ios CALayer 文档:

“在 iOS 中,如果图层与 UIView 对象相关联,则必须将此属性设置为拥有该图层的视图。”

【讨论】:

大概“与一个 UIView 对象相关”意味着该层是视图的根层(由layer 属性引用)。对于 UIView 根层的子层,委托绝对可以是视图对象以外的其他东西。【参考方案5】:

如果您有一个多线程应用程序,其中后台处理驱动需要更新 CALayer,您必须在主线程中调用 setNeedsDisplay

【讨论】:

以上是关于CALayer委托方法drawLayer没有被调用的主要内容,如果未能解决你的问题,请参考以下文章

animationDidStop:完成:委托方法没有被调用

有没有办法让 CALayer 的动作字典永久优先于其 UIView 委托?

IOS中drawLayer使用CGContent

CALayer 从当前值淡出

CALayer - 未调用显示方法

iOS:使用 UIView 的 'drawRect:' 与其层的委托 'drawLayer:inContext:'