我在所有互联网网站上挖掘并找不到解决方案。我的问题是用CAKeyframeAnimation改变CALayer的位置。动画结束后,我无法设置图层位置的最终值(位置重置为最终值)。所有教程,示例和答案都包含两个信息:在向图层添加动画之前或之后将最终值设置为模型图层(换句话说,立即),但这不能按预期工作。取而代之的是我必须在CATransaction的完成块中设置最终值,但这会导致闪烁(图层的位置重置为初始值,然后设置为最终值)。这是我的代码和一些评论。
CGPoint originalPosition = self.mainContainerView.contentContainerView.layer.position;
[CATransaction lock];
[CATransaction begin];
[CATransaction setCompletionBlock:^{
//Setting final value works here, but layer resets to initial position and then this line is invoked (ugly flicker effect)
self.mainContainerView.contentContainerView.layer.position = CGPointMake(originalPosition.x, originalPosition.y + _menuOffset);
_menuViewState = MenuViewStateOpened;
[self.mainContainerView.contentContainerView.layer removeAllAnimations];
}];
_menuOffset = self.mainContainerView.menuContainerView.frame.size.height;
CAKeyframeAnimation *keyframeAnimation = [CAKeyframeAnimation animationWithKeyPath:@"position"];
keyframeAnimation.path = [self getBounceCGPath];
keyframeAnimation.keyTimes = @[@0, @(2 / 6.0), @(3 / 6.0), @(4 / 6.0), @(5 / 6.0), @1];
keyframeAnimation.duration = 0.4;
//Without this two lines ugly flicker appears (final value is not set, so this is workaround)
keyframeAnimation.fillMode = kCAFillModeForwards;
keyframeAnimation.removedOnCompletion = NO;
//-------------------------------------------
//This should prevent for setting final value before animation starts
[CATransaction setDisableActions:YES];
//Setting final value (for unknown reason this is not working, moving this line after 'addAnimation' method does not work either)
self.mainContainerView.contentContainerView.layer.position = CGPointMake(originalPosition.x, originalPosition.y + _menuOffset);
[self.mainContainerView.contentContainerView.layer addAnimation:keyframeAnimation
forKey:@"reveal"];
[CATransaction commit];
[CATransaction unlock];
答案 0 :(得分:1)
我总是在添加动画之前设置新值,它工作正常。所以不要只为完成块而烦恼:
_menuOffset = self.mainContainerView.menuContainerView.frame.size.height;
self.mainContainerView.contentContainerView.layer.position = CGPointMake(originalPosition.x, originalPosition.y + _menuOffset);
CAKeyframeAnimation *keyframeAnimation = [CAKeyframeAnimation animationWithKeyPath:@"position"];
keyframeAnimation.path = [self getBounceCGPath];
keyframeAnimation.keyTimes = @[@0, @(2 / 6.0), @(3 / 6.0), @(4 / 6.0), @(5 / 6.0), @1];
keyframeAnimation.duration = 0.4;
keyframeAnimation.removedOnCompletion = NO;
[self.mainContainerView.contentContainerView.layer addAnimation:keyframeAnimation forKey:@"reveal"];
设置图层的新动画值应该是你要做的第一件事,除非你想要它回弹。