在哪里调用 setNeedsDisplay 来更新 CALayer?

Posted

技术标签:

【中文标题】在哪里调用 setNeedsDisplay 来更新 CALayer?【英文标题】:Where to call setNeedsDisplay in order to update CALayer? 【发布时间】:2015-06-20 23:02:14 【问题描述】:

我有一个视图控制器 (MagmaViewController),它正在管理一个名为 MagmaView 的视图。对于MagmaView 的直接支持层,我通过将以下内容放入MagmaView 的实现部分来分配我自己的自定义CALayer 子类MagmaLayer

+ (Class)layerClass

    return [MagmaLayer class];

我有一些自定义的绘图,我希望MagmaLayerMagmaView 绘制,所以我将一些绘图代码放入MagmaLayer-(void) drawInContext:(CGContextRef) context 方法中。问题是当我这样做并运行模拟器时,MagmaView 显示为空白。我在MagmaLayer-(void) drawInContext:(CGContextRef) context 方法中设置了一个断点,看来这个方法根本没有被调用。

显然,我对触发此 CALayer 绘图的 setNeedsDisplay 命令的需求和位置感到困惑。首先,我认为,至少对于 CALayer 的第一次初始外观,如果 CALayer 是 UIView 的直接支持层,则不需要发出setNeedsDisplay 命令,并且任何 UIView 都确保其直接支持层在需要时正确绘制,并且只有非直接 CALayer 支持层需要特别注意以确保它们自己绘制。不是这样吗?另外,我应该在哪里放置setNeedsDisplay 命令以使这个直接支持层MagmaLayer 自行绘制? setNeedsDisplay 命令是否应该在MagmaView 的初始化方法中,也就是这里托管MagmaLayer 的视图?或者我应该更进一步,将setNeedsDisplay 命令放入MagmaViewController,即管理MagmaView 的视图控制器,例如控制器的viewWillAppear 方法?

【问题讨论】:

【参考方案1】:

您需要告诉您的自定义图层何时绘制。基本实现不会自动调用-(void) drawInContext:(CGContextRef) context。基本设置是在层初始化方法中设置needsDisplayOnBoundsChange = YES。 如果您有应该触发重绘的自定义属性,则必须实现/扩展+ (BOOL)needsDisplayForKey:(NSString *)key

【讨论】:

以上是关于在哪里调用 setNeedsDisplay 来更新 CALayer?的主要内容,如果未能解决你的问题,请参考以下文章

更新 Label.text setNeedsDisplay() 不起作用 - Swift

调用 setNeedsDisplay 时的 Swift 奇怪行为

-setNeedsDisplay 没有被调用来刷新 drawRect

setNeedsDisplay 只被调用一次

setNeedsDisplay setNeedsLayout

UIView setNeedsDisplay 没有效果?