当我在动画UIView的边界时,如何重绘UIView的子层?

7

我有一个UIView,里面有几个自定义绘制的子层(一些使用CAShapeLayer掩码的CAGradientLayers等)。 我使用UIView动画方法来动画化它的边界(增加其宽度和高度)。

[UIView animateWithDuration:2 delay:0 options:UIViewAnimationOptionCurveEaseOut|UIViewAnimationOptionAutoreverse|UIViewAnimationOptionRepeat animations:^{
    CGRect bounds = myView.bounds;
    bounds.size.width += 20;
    bounds.size.height += 20;
    myView.bounds = bounds;
} completion:nil];

这个方案很好,但是子层在动画过程中不会被重绘。最佳的解决方法是什么?我需要设置一些键值观察来检测边界变化,并在所有子层上调用setNeedsDisplay吗?

2个回答

8

在进行视图动画时,将视图的contentMode设置为UIViewContentModeRedraw


4

图层和视图的工作方式不同。如果在父图层上调用setNeedsDisplay(如果您已将needsDisplayOnBoundsChange设置为YES,则会发生这种情况),它不会影响子图层。您需要同时调用setNeedsDisplay来更新子图层。

如果在父图层调整大小时,其子图层也需要调整大小,则应在父图层中实现layoutSublayers(或在其委托中实现layoutSublayersOfLayer:)。


2
你说得没错,但这仍然没有解决一个大问题,那就是调整图层/子图层的大小和重绘图层/子图层之间存在很大的区别。我的问题是,即使有有效的委托和needsDisplayOnBoundsChange = YES,当图层的边界动画时,它们也不会调用它们的drawLayer:方法。 - zakdances
你是在代理方法drawLayer:inContext:中实现绘图代码吗? - aLevelOfIndirection
1
是的,它可以正常绘制。只有在我对边界进行动画处理时才会出现问题。如果我只是像self.layer.bounds = newBounds或self.bounds = newBounds这样改变边界,它在立即图层上可以正常工作(尽管我必须手动更改子图层,就像你说的那样)。 - zakdances
你关于需要在iOS视图上单独管理子层的说法是正确的。如果在其中加入一句话,说明层的边界在动画期间不会持续变化(它们只会在其presentationLayer上改变),我会给你打勾勾。 - zakdances
这实际上是事实。modelLayer立即获取最终动画值,而presentationLayer获取的是动画值。 - aLevelOfIndirection

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接