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下载