ios 动画系列之五------复杂的动画实现

前言:前面我们介绍过两种简单的动画实现,一种是直接利用UIView的beginAnimations等,另一种是利用CATransition *transition。在上一篇博客中我们又详细学习了动画的原理,那么在这一节中,我们将实现一些稍微复杂一点的动画。

本文代码参考自:http://blog.csdn.net/totogo2010/article/details/8606089,尊重原创!

1、实现圆弧运动

-(void)changeUIView4{    
    //路径曲线
    UIBezierPath *movePath = [UIBezierPath bezierPath];
    CGPoint fromPoint = self.imageView.center;
    CGPoint endPoint = CGPointMake(280, 400);
    [movePath moveToPoint:fromPoint];
    //画二元曲线,结束点、控制点
    [movePath addQuadCurveToPoint:endPoint controlPoint:CGPointMake(280,0)];
    //关键帧
    //创建一个Animation对象,把它的keypath属性的值设为"position"
    CAKeyframeAnimation *moveAnim = [CAKeyframeAnimation animationWithKeyPath:@"position"];
    //moveAnim.path = movePath.CGPath;//用path实现
    
    NSMutableArray *values=[NSMutableArray array];
    for (int i=0; i<3; i++) {
        [values addObject:[NSValue valueWithCGPoint:CGPointMake(250*cos(M_PI*2.0/10*i),
                                                                250*sin(M_PI*2.0/10*i))]];
    }
    moveAnim.values = values;//用values实现
    moveAnim.removedOnCompletion = YES;
    
    //旋转变化,scaleAnim设置了缩小
    CABasicAnimation *scaleAnim = [CABasicAnimation animationWithKeyPath:@"transform"];
    scaleAnim.fromValue = [NSValue valueWithCATransform3D:CATransform3DIdentity];
    //x,y轴缩小到0.3,Z 轴不变
    scaleAnim.toValue = [NSValue valueWithCATransform3D:CATransform3DMakeScale(0.3, 0.3, 1.0)];
    scaleAnim.removedOnCompletion = YES;
    
    //透明度变化,opacityAnim设置了透明度的变化
    CABasicAnimation *opacityAnim = [CABasicAnimation animationWithKeyPath:@"alpha"];
    opacityAnim.fromValue = [NSNumber numberWithFloat:1.0];
    opacityAnim.toValue = [NSNumber numberWithFloat:0.2];
    opacityAnim.removedOnCompletion = YES;
    
    //关键帧,旋转,透明度组合起来执行
    CAAnimationGroup *animGroup = [CAAnimationGroup animation];
    //数组[CAAnimation对象],数组里的每个对象同时运行
    animGroup.animations = [NSArray arrayWithObjects:moveAnim, scaleAnim,opacityAnim, nil];
    animGroup.duration = 1;
    animGroup.removedOnCompletion = NO;
    animGroup.fillMode = kCAFillModeForwards;
    [_imageView.layer addAnimation:animGroup forKey:nil];
}

上面对关键帧的实现,我们分别使用了path和values方法。利用path那个可以把图片移到右下角,利用values这个是让图片绕一个圆弧运动。我们分别设置了透明度、放大缩小等,然后把这三个动画一起加入animGroup。最后把animGroup加到layer上就实现了动画。说明一点:我们可以一次加上很多动画效果到animGroup,它们是同时运行的。当然,也可以不加入animGroup,而把各个动画效果分别自己添加到layer.
animGroup.removedOnCompletion = NO; animGroup.fillMode = kCAFillModeForwards;这两句话设置了对象不再动画期间的行为,具体参考上一篇博文。

2、旋转并向右移动

//旋转并向右移动
- (void)changeUIView5 {
    CGPoint fromPoint = self.imageView.center;
    UIBezierPath *movePath = [UIBezierPath bezierPath];
    [movePath moveToPoint:fromPoint];
    CGPoint toPoint = CGPointMake(fromPoint.x +100 , fromPoint.y ) ;
    [movePath addLineToPoint:toPoint];
    
    CAKeyframeAnimation *moveAnim = [CAKeyframeAnimation animationWithKeyPath:@"position"];
    moveAnim.path = movePath.CGPath;
    
    CABasicAnimation *TransformAnim = [CABasicAnimation animationWithKeyPath:@"transform"];
    TransformAnim.fromValue = [NSValue valueWithCATransform3D:CATransform3DIdentity];
    
    //沿Z轴旋转
    TransformAnim.toValue = [NSValue valueWithCATransform3D: CATransform3DMakeRotation(M_PI,0,0,1)];
    
    //沿Y轴旋转
  //scaleAnim.toValue = [NSValue valueWithCATransform3D: CATransform3DMakeRotation(M_PI,0,1.0,0)];
    
    //沿X轴旋转
//  TransformAnim.toValue = [NSValue valueWithCATransform3D: CATransform3DMakeRotation(M_PI,1.0,0,0)];
    TransformAnim.cumulative = YES;
    TransformAnim.duration =3;
    //旋转2遍,360度
    TransformAnim.repeatCount =2;
    self.imageView.center = toPoint;
    TransformAnim.removedOnCompletion = YES;
    CAAnimationGroup *animGroup = [CAAnimationGroup animation];
    animGroup.animations = [NSArray arrayWithObjects:moveAnim, TransformAnim, nil];
    animGroup.duration = 6;
    
    [self.imageView.layer addAnimation:animGroup forKey:nil];
}

向右移动是因为关键帧使用了路径为直线的路径。沿Z轴旋转是靠TransformAnim.toValue = [NSValue valueWithCATransform3D: CATransform3DMakeRotation(M_PI,0,0,1)];  

3、旋转并消除边缘锯齿

如果你仔细观察,会看到第二个动画里在旋转时,图片边缘是有锯齿的,如何消除呢?在图片边缘添加一个像素的透明区域,去图片锯齿。

UIGraphicsBeginImageContext 开始图片内容

UIGraphicsGetImageFromCurrentImageContext 获取当前内容作为图片,

UIGraphicsEndImageContext结束。是和UIGraphicsBeginImageContext配套使用的。

- (void)changeUIView6 {
    //图片旋转360度
    CABasicAnimation *animation = [ CABasicAnimation
                                   animationWithKeyPath: @"transform" ];
    animation.fromValue = [NSValue valueWithCATransform3D:CATransform3DIdentity];
    
    //围绕Z轴旋转,垂直与屏幕
    animation.toValue = [ NSValue valueWithCATransform3D:
                         CATransform3DMakeRotation(M_PI, 0, 0, 1.0) ];
    animation.duration = 3;
    //旋转效果累计,先转180度,接着再旋转180度,从而实现360旋转
    animation.cumulative = YES;
    animation.repeatCount = 2;
    
    //在图片边缘添加一个像素的透明区域,去图片锯齿
    CGRect imageRrect = CGRectMake(0, 0, self.imageView.frame.size.width, self.imageView.frame.size.height);
    UIGraphicsBeginImageContext(imageRrect.size);
    [self.imageView.image drawInRect:CGRectMake(1,1,self.imageView.frame.size.width-2,self.imageView.frame.size.height-2)];
    self.imageView.image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    
    [self.imageView.layer addAnimation:animation forKey:nil];
}

至此,动画这一个专题也差不多学完了,为了巩固和检查学习效果,我决定在网上找一个简单的动画示例自己模仿着做一做。

前面讲过的实现的所有代码:AnimationDemo.zip下载

 

原文地址:https://www.cnblogs.com/wyqfighting/p/3209041.html