零速度的CALayer不会改变它的位置

时间:2015-02-05 16:13:32

标签: ios core-animation calayer

我正在实施自定义 pull-to-refresh 组件。

使用微调器动画创建 CALayer ,而不是将此图层添加到 UICollectionView 。图层的速度为零(self.loaderLayer.speed = 0.0f;),图层动画通过scrollViewDidScroll:中的 timeOffset 进行管理。问题出现在这里,因为我还想显示一个加载器总是在拉空间的中心,所以我改变了scrollViewDidScroll:中图层的位置,如下所示:

[self.loaderLayer setPosition:CGPointMake(CGRectGetMidX(scrollView.bounds), scrollView.contentOffset.y / 2)];

但是层位置没有任何反应(调用[self.loaderLayer setNeedsDisplay]没有帮助)。我明白这是因为零速度。目前我找到了有效的方式(但我不喜欢):

self.loaderLayer.speed = 1.0f;
[self.loaderLayer setPosition:CGPointMake(CGRectGetMidX(scrollView.bounds), scrollView.contentOffset.y / 2)];
self.loaderLayer.speed = 0.0f;

如何更改暂停图层的位置?我错过了什么?

1 个答案:

答案 0 :(得分:0)

关于@David的所有问题以供参考。我只是总结一下作为答案。

CoreAnimation 适用于两种动画(事务):显式隐式。当您在属性文档中看到Animatable字时,这意味着每次设置此属性时, CoreAnimation 都会对此属性进行动画更改隐式具有系统默认持续时间(默认为1/4秒)。引擎盖 CALayer 对这些属性有操作,并且调用-actionForKey返回此类操作(隐式动画)。

所以在我的情况下,当我更改图层位置时, CoreAnimation 会隐式尝试设置此更改的动画。由于图层已暂停(速度为零)动画具有默认持续时间,因此我们不会直观地看到此更改。

答案是禁用隐式动画(禁用调用图层-actionForKey)。为此,我们致电[CATransaction setDisableActions:YES]

我们可以通过调用[CATransaction setAnimationDuration:0.0];将此动画标记为立即(通过将其持续时间设置为零)。

这些标记/更改是基于每个线程的,并且适用于特定线程中的所有事务,直到下一个运行循环。因此,如果我们想将它们应用于具体事务,我们将代码与[CATransaction begin]; ... [CATransaction commit];部分包装在一起。

在我的情况下,最终代码看起来

[CATransaction begin];
[CATransaction setDisableActions:YES];
[self.loaderLayer setPosition:CGPointMake(CGRectGetMidX(scrollView.bounds), scrollView.contentOffset.y / 2)];
self.loaderLayer.transform = CATransform3DMakeScale(scaleFactor, scaleFactor, 1);
[CATransaction commit];

它完美无缺!

Loader Demo