Iphone 使用CAAnimation实现CATTransition推送

Iphone 使用CAAnimation实现CATTransition推送,iphone,ios,core-animation,caanimation,catransition,Iphone,Ios,Core Animation,Caanimation,Catransition,如何在iOS中使用CAAnimation子类实现kCATransitionPush CAAnimation *animation; // How do you create an animation that does the same than: // CATransition *animation = [CATransition animation]; // [animation setType:kCATransitionPush]; [self.view.layer add

如何在iOS中使用
CAAnimation
子类实现
kCATransitionPush

CAAnimation *animation;
// How do you create an animation that does the same than:
// CATransition *animation = [CATransition animation];
// [animation setType:kCATransitionPush];        
[self.view.layer addAnimation:animation forKey:nil];

[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:1];        
[self.view addSubview:change];
[UIView commitAnimations];

我知道可以使用
UIView
动画,但如果我能实现从底层向上的
kCATransitionPush
转换,这将有助于我更好地理解核心动画。要使用自己的
CABasicAnimation
复制转换,首先需要了解推送动画是如何工作的。我这样做时没有测试,所以这可能是关闭的,但是如果我正确地记得子层B替换子层A的动画是这样工作的:

CABasicAnimation *anim = [CABasicAnimation animationWithKeyPath:@"position"];
anim.fromValue = [NSValue valueWithCGPoint:startPoint];
anim.toValue = [NSValue valueWithCGPoint:endPoint];

CABasicAnimation *anim = [CABasicAnimation animationWithKeyPath:@"opacity"];
anim.fromValue = [NSNumber numberWithFloat:0.0];
anim.toValue = [NSNumber numberWithFloat:1.0];
  • 图层A从原始位置向右移动
  • 层B从A的右侧移动到原始位置
  • li动画层B的前半部分将其不透明度设置为从0到1的动画
  • 动画层A的后半部分设置其不透明度从1到0的动画 (当然,您可以在此处用任意方向替换右侧)
CABasicAnimation
仅支持对一个属性设置动画,因此您必须创建一个控制4个不同动画的
CAAnimationGroup

创建位置和不透明度的动画,如下所示:

CABasicAnimation *anim = [CABasicAnimation animationWithKeyPath:@"position"];
anim.fromValue = [NSValue valueWithCGPoint:startPoint];
anim.toValue = [NSValue valueWithCGPoint:endPoint];

CABasicAnimation *anim = [CABasicAnimation animationWithKeyPath:@"opacity"];
anim.fromValue = [NSNumber numberWithFloat:0.0];
anim.toValue = [NSNumber numberWithFloat:1.0];

为了在两个层上同时执行动画,必须向每个层添加足够的CAAnimationGroup

[nextView.layer addAnimation:nextViewAnimation forKey:nil];
[currentView.layer addAnimation:currentViewAnimation forKey:nil];
下一步设想是:

CAAnimationGroup *nextViewAnimation = [CAAnimationGroup animation];
NSMutableArray *nextAnimations = [NSMutableArray array];

[nextAnimations addObject:[self opacityAnimation:YES]];  // fade in

CGPoint fromPoint = CGPointMake(forward ? nextView.center.x + nextView.frame.size.width : nextView.center.x - nextView.frame.size.width, nextView.center.y);
[nextAnimations addObject:[self positionAnimationFromPoint:fromPoint toPoint:nextView.center]];  // traslation in

nextViewAnimation.animations = nextAnimations;
和currentViewAnimation:

CAAnimationGroup *currentViewAnimation = [CAAnimationGroup animation];
NSMutableArray *currentAnimations = [NSMutableArray array];
[currentSceneAnimations addObject:[self opacityAnimation:NO]]; // fade out

CGPoint toPoint = CGPointMake(forward ? currentView.center.x - currentView.frame.size.width : currentView.center.x + currentView.frame.size.width, currentView.center.y);
    [currentAnimations addObject:[self positionAnimationFromPoint:currentView.center toPoint:toPoint]];  // traslation out

currentViewAnimation.animations = currentAnimations;
这些方法创建基本动画:

- (CABasicAnimation *)opacityAnimation:(BOOL)fadeIn {
CABasicAnimation *a = [CABasicAnimation animationWithKeyPath:@"opacity"];
a.fromValue = [NSNumber numberWithFloat:fadeIn ? 0.0 : 1.0];
a.toValue = [NSNumber numberWithFloat:fadeIn ? 1.0 : 0.0];
return a;
}

- (CABasicAnimation *)positionAnimationFromPoint:(CGPoint)fromPoint toPoint:(CGPoint)toPoint {
CABasicAnimation *a = [CABasicAnimation animationWithKeyPath:@"position"];
a.fromValue = [NSValue valueWithCGPoint:fromPoint];
a.toValue = [NSValue valueWithCGPoint:toPoint];
return a;
}

使用布尔值向前
可以模拟“从左”或“从右”的转换

谢谢你,乔里斯。不是视图A替换了视图B。是视图的原始状态被新状态替换。对不起,不知为什么我使用了“视图”这个词,我应该在这里使用CALayer。一个转换确实对视图内容有效:我不知道苹果的实现,可能是OpenGL支持CALayer内容动画。最好的方法是自己使用上面描述的应用于子层的方法。您如何区分子层A和子层B?CATTransition似乎自动完成了这项工作。