零速度的CALayer不会改变它的位置
Posted
技术标签:
【中文标题】零速度的CALayer不会改变它的位置【英文标题】:CALayer with zero speed doesn't change it's position 【发布时间】:2015-02-05 16:13:31 【问题描述】:我正在实现一个自定义的 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;
如何更改暂停图层的位置?我错过了什么?
【问题讨论】:
将speed
设置为0.0f
会导致该图层的所有动画暂停;包括定位。实现“微调器动画暂停”的方法可能与您正在执行的方法不同,但如果不查看如何构建微调器层的代码,就很难说出那是什么。
只需使用两个不同的层,一个用于设置零速度,另一个用于重新定位。一个可以包含另一个。
是的,将用第二层包裹。我只是认为,无论暂停状态如何,都有一种正确的方法可以强制更新位置。谢谢
How do you move a CALayer instantly (w/o animation) 的可能重复图层不会移动,因为默认情况下setPosition
是动画的,并且您将动画速度设置为零。所以在没有动画的情况下移动它。
@David 感谢您的参考,这正是我想要的:)
【参考方案1】:
所有关于 @David 的参考。我只是把它总结为一个答案。
CoreAnimation 适用于两种动画(事务):显式和隐式。当您在 property 文档中看到 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];
而且效果很好!
【讨论】:
以上是关于零速度的CALayer不会改变它的位置的主要内容,如果未能解决你的问题,请参考以下文章
滚动视图滚动时,有任何更好的方法可以无延迟地更改CAlayer位置