Ios 零速CALayer不';不要改变它';s位置

Ios 零速CALayer不';不要改变它';s位置,ios,core-animation,calayer,Ios,Core Animation,Calayer,我正在实现一个自定义的拉刷新组件 使用微调器动画创建CALayer,然后将该层添加到UICollectionView。层的速度为零(self.loaderLayer.speed=0.0f;),层动画通过scrollViewDidScroll:中的时间偏移进行管理。问题出在这里,因为我还想显示一个加载程序总是在拉动空间的中心,所以我在scrollViewDidScroll:中更改层的位置,如下所示: [self.loaderLayer setPosition:CGPointMake(CGRectG

我正在实现一个自定义的拉刷新组件

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

[self.loaderLayer setPosition:CGPointMake(CGRectGetMidX(scrollView.bounds), scrollView.contentOffset.y / 2)];
但是图层位置没有任何变化(调用
[self.loaderLayer setNeedsDisplay]
没有帮助)。我明白这是因为零速度。目前我找到了有效的方法(但我不喜欢):


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

所有关于@David的信息仅供参考。我只是把它概括为一个答案

CoreAnimation使用两种动画(事务):显式和隐式。当您在属性文档中看到
Animatable
word时,这意味着每次设置此属性时,CoreAnimation都会以系统默认持续时间(默认值为
1/4
秒)隐式地设置此属性更改的动画。在hoodCALayer下,对这些属性执行操作,并调用
-actionForKey
返回此类操作(隐式动画)

因此,在我的例子中,当我更改层位置时,CoreAnimation会隐式地尝试设置此更改的动画。由于层已暂停(速度为零),并且动画具有默认持续时间,因此我们无法从视觉上看到此更改

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

我们可以通过调用
[CatTransaction 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];
而且它工作得很好


速度设置为
0.0f
会暂停该层的所有动画;包括定位。可能有一种不同的方法来实现“微调器动画暂停”,但如果没有看到构建微调器层的代码,很难说这是什么。只需使用两个不同的层,一个设置为零速度,另一个要重新定位。一个可以包含另一个。是的,将用第二层包裹。我只是认为,有一种正确的方法,不管暂停状态如何,都可以强制更新位置。Thanks层的可能副本不会移动,因为默认情况下,
setPosition
已设置动画,并且动画速度设置为零。所以,不用动画就移动它。@David谢谢你的参考,这正是我想要的:)
[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];