【问题标题】:Implementing a CATransition push with CAAnimation使用 CAAnimation 实现 CATransition 推送
【发布时间】:2011-04-09 11:25:34
【问题描述】:

如何在 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 动画可以使用also,但如果我可以从头开始实现kCATransitionPush 过渡,这将有助于我更好地理解核心动画 .

【问题讨论】:

    标签: iphone ios core-animation caanimation catransition


    【解决方案1】:

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

    [nextView.layer addAnimation:nextViewAnimation forKey:nil];
    [currentView.layer addAnimation:currentViewAnimation forKey:nil];
    

    nextViewAnimation 将是:

    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;
    }
    

    使用布尔值forward,您可以模拟“从左”或“从右”的过渡。

    【讨论】:

      【解决方案2】:

      默认的kCATransitionPush 确实包含淡入淡出。要使用您自己的CABasicAnimation 复制过渡,您首先需要了解推送动画的工作原理。我没有测试就这样做了,所以这可能会关闭,但如果我没记错的话,子层 B 替换子层 A 的动画是这样的:

      • A 层从原始位置向右移动
      • B 层从右侧移动到 A 的原始位置
      • 动画层 B 的前半部分将其不透明度从 0 设置为 1
      • 动画层 A 的后半部分将其不透明度从 1 设置为 0 (当然你可以在这里用任意方向替换right)。

      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];
      

      【讨论】:

      • 谢谢乔里斯。不是视图 A 替换了视图 B。而是视图的原始状态被新状态替换。
      • 抱歉,不知何故我使用的是单词视图,我应该使用 CALayer。转换确实适用于视图内容:我不知道 Apple 的实现,也可能是支持 CALayer 内容动画的 OpenGL。自己做的最好方法是将上述方法应用于子层。
      • 如何区分子层 A 和子层 B? CATransition 似乎会自动执行此操作。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-11-22
      • 2017-12-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多