立即更新 CALayer 子层

Posted

技术标签:

【中文标题】立即更新 CALayer 子层【英文标题】:Update CALayer sublayers immediately 【发布时间】:2015-12-20 11:44:22 【问题描述】:

我的 UIView 具有以下结构:

UIView
  |- layer (CALayer)
    |- depthLayer (CALayer)
    |- bodyLayer (CALayer)

对于 layer 我设置了 needsDisplayOnBoundsChange = true。当我改变 UIView 的大小时,layer 会立即重绘。但是它们的子层会延迟更新(在下一次绘制迭代中)。如何同步绘制 layers 与子层 depthLayerbodyLayer

UIView:

override func drawRect(rect: CGRect) 
    bodyLayer.frame = rect
    depthLayer.frame = CGRectOffset(rect, 0, 5)

【问题讨论】:

您为什么不尝试覆盖 setFrame 方法并在其中设置所有帧,另外请注意,CALayers 将尝试使用关键帧动画(或其他任何名称)为 Frame Change 设置动画 - -> 要禁用动画,您应该参考这个问题:***.com/questions/226354/… 谢谢!我只是用 CATransaction 将帧更新包装在 drawRect: 中。 不客气先生 :-) 【参考方案1】:

您在CALayer's frames 中看到的延迟是因为 动画 -> 当您更改 CALayer's 外观时 它尝试对其进行动画处理(并且通常会成功 -> 这就是他们称为动画层的原因)。

要禁用此行为(动画),您应该像这样调用禁用事务:

CATransaction.setValue(kCFBooleanTrue, forKey:kCATransactionDisableActions) //..Make Change to the frames here CATransaction.commit()

另外我不知道你是否真的需要覆盖drawRect 对于这件事->如果您通过setFrame:方法设置UIView's Frame, 最好重写setFrame:方法本身并在那里调整子图层的Frames。

祝你好运!

【讨论】:

我认为我不使用 setFrame: 方法,通过更新自动布局约束来更新 UIView 大小。我只是想简化我的问题,这就是为什么我没有在问题中提及它。如果我错了,请告诉我。谢谢。 好吧,我不确定 :-) 只是说如果你用 setFrame 来做,那就更充分了 ;-) 我也不确定 AutoLayout 是否调用 setFrame - 你可以通过覆盖 setFrame 并在那里打印来检查它 -> 然后告诉我,我也会知道 :) 效果很好!我写了下面的 CATransation.setValue.... //这里我添加了子层 CATransaction.commit()

以上是关于立即更新 CALayer 子层的主要内容,如果未能解决你的问题,请参考以下文章

如何在正确的位置渲染 CALayer 子层

如何在缩放的 CALayer 中保持子层的比例

在 UIImageView 上一致地居中 CALayer 子层

如何保持 CALayer(CATiledLayer 的子层)在缩放后不改变其比例?

CALayer 没有实现自定义 drawLayer:inContext: 方法

IOS CALayer