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没有被调用的主要内容,如果未能解决你的问题,请参考以下文章