动画Animation
一、UIView基础动画
UIKit 直接将动画继承到UIView类中,当内部的一些属性发生改变时,UIView将为这些改变提供动画支持。
执行动画的工作由UIView类自动完成,但仍希望在执行动画时通知视图,为此需要将改变属性的代码放在
[UIVIew beginAnimations:nil context:nil]与[UIView commitAnimations]之间。
1.UIView简单动画
//UIKit集成的UIView上的动画,动画块 -(void)beginAndCommitAnimation { self.redView.frame = CGRectMake(100, 100, 100, 100); //开始设置动画 //参数1.当前动画的标签 //参数2.上下文,如果为动画设置代理,context可以作为代理方法的参数 [UIView beginAnimations:@"move" context:@"移动"]; //设置动画时长 [UIView setAnimationDuration:5]; //设置重复次数 [UIView setAnimationRepeatCount:3]; //设置逆向效果 [UIView setAnimationRepeatAutoreverses:YES]; //动画延迟 [UIView setAnimationDelay:0.2]; //动画的速度曲线,缓慢开始,缓慢结束等 [UIView setAnimationCurve:UIViewAnimationCurveEaseIn]; //设置动画的代理 [UIView setAnimationDelegate:self]; //添加动画开始时执行的代理方法 [UIView setAnimationWillStartSelector:@selector(animationDidStart: context:)]; //动画结束后的代理方法 [UIView setAnimationDidStopSelector:@selector(animationDidStop:)]; //设置要改变的属性 CGRect rect = self.redView.frame; rect.origin.x = 250; rect.origin.y = 500; rect.size.width = 50; rect.size.height = 50; self.redView.frame = rect; _redView.alpha = 0.2; _redView.backgroundColor = [UIColor blueColor]; //提交动画 [UIView commitAnimations]; } #pragma mark -- 动画的代理方法 -(void)animationDidStart:(NSString *)animID context:(NSString*)context { NSLog(@"动画开始的代理--%@",context); } -(void)animationDidStop:(NSString *)animID { NSLog(@"动画结束--%@",animID); }2.block简单动画
//block动画 -(void)blockAnimation { [UIView animateWithDuration:2 animations:^{ //设置动画重复次数和可逆 [UIView setAnimationRepeatCount:5]; [UIView setAnimationRepeatAutoreverses:YES]; //要改变的属性 [self.redView setBackgroundColor:[UIColor greenColor]]; }]; }
block过渡动画
//transition fromView效果 -(void)tranFromViewAnimation { //两个界面的翻转效果 /*中间的效果是 [self.redView.supperView addSubView self.greenView]; [self.redView removeFromSuperView]; fromView的参数必须有父视图 */ //从一个view到另一个view [UIView transitionFromView:self.redView toView:self.greenView duration:2 options:UIViewAnimationOptionTransitionFlipFromLeft completion:^(BOOL finished) { NSLog(@"block end"); }]; }
block关键帧动画
之所以叫做关键帧动画是因为,这个类可以实现,某一属性按照一串的数值进行动画,就好像制作动画的时候一帧一帧的制作一样。
//一帧动画 -(void)keyFrameAnimation { //动画执行的总时长 //延时 //option动画效果 //animation帧动画的配置 //completion动画结束后 [UIView animateKeyframesWithDuration:1 delay:0 options:UIViewKeyframeAnimationOptionRepeat animations:^{ //每帧。。 //执行一次动画的时间为 总时长*relativeDuration //startTime和relativeDuration的范围是0~1之间 //执行完要等待 总时长 才会才会执行下一次 ,在repeat状态下 [UIView addKeyframeWithRelativeStartTime:0.0 relativeDuration:0.25 animations:^{ self.redView.frame = CGRectMake(100, 400, 200, 200); }]; } completion:^(BOOL finished) { NSLog(@"block end"); }]; }
这个文章说的比较明白http://www.renfei.org/blog/ios-8-spring-animation.html
//用spring可以实现弹簧效果或者果冻效果 -(void)springAnimation { //damp阻尼 0~1 越大阻尼越大 //velocity速率 速率越大 频率越快 [UIView animateWithDuration:2 delay:0 usingSpringWithDamping:0.1 initialSpringVelocity:2 options:UIViewAnimationOptionRepeat animations:^{ self.redView.frame = CGRectMake(50, 500, 200, 200); } completion:nil]; }
CoreAnimation动画位于iOS框架的Media层
需要添加QuartzCore.Framework(系统自动添加)
CoreAnimation基本上是Layer Animation
CALayer负责绘制,提供UIView需要展示的内容,不能交互。
UIView负责交互,显示CALayer绘制的内容。
Layer有很多种,最常用和最基本的是CALayer,还有它的子类:
CAScrollerLayer简化显示层的一部分
CATextLayer文本层
CAGradientLayer可以方便的处理颜色渐变、CAShapeLayer仅仅限于沿着边缘的动画效果,它实现不了填充效果
关于CALayer这篇文章很全http://www.cnblogs.com/wengzilin/p/4250957.htmlhttp://
再说一下
隐式动画:不用指定任何动画类型,仅仅改变一个属性,然后CoreAnimation来觉得如何及何时去做动画
显示动画:UI一下属性做指定的自定义动画,或者创建非线性动画,比如沿着任意一条曲线移动
与UIView动画相比,CoreAnimation能够实现更多复杂、好看、高效的动画:
阴影、圆角、带颜色的边框
3D变换
透明遮罩
多级非线性动画
//基本动画 -(CABasicAnimation*)basicAnimation { //隐式动画 scale.x rottion CABasicAnimation *basicAnimation = [CABasicAnimation animationWithKeyPath:@"transform.scale"]; //动画变化的初始值 basicAnimation.fromValue = @(1); //效果变化结束值(绝对值) basicAnimation.toValue = @(2); //效果变化结束值(相对值),在原本的状态下增加的 // basicAnimation.byValue = @(2); //设置时长 basicAnimation.duration = 1; //动画结束后是否反向恢复 basicAnimation.autoreverses = YES; //每次动画结束后,将动画产生的效果从layer层上移除掉,默认值为YES basicAnimation.removedOnCompletion = NO; //填充属性,状态模式 //kCAFillModeRemoved 这个是默认值,也就是说当动画开始前和动画结束后,动画对layer都没有影响,动画结束后,layer会恢复到之前的状态 //kCAFillModeForwards 当动画结束后,layer会一直保持着动画最后的状态 //kCAFillModeBackwards 这个和kCAFillModeForwards是相对的,就是在动画开始前,你只要将动画加入了一个layer,layer便立即进入动画的初始状态并等待动画开始.你可以这样设定测试代码,将一个动画加入一个layer的时候延迟5秒执行.然后就会发现在动画没有开始的时候,只要动画被加入了layer,layer便处于动画初始状态 //kCAFillModeBoth 理解了上面两个,这个就很好理解了,这个其实就是上面两个的合成.动画加入后开始之前,layer便处于动画初始状态,动画结束后layer保持动画最后的状态. basicAnimation.fillMode = kCAFillModeBackwards; return basicAnimation; //添加动画 [self.greenView.layer addAnimation:basicAnimation forKey:@"basic"]; } //关键帧动画 -(CAKeyframeAnimation*)layerKeyFrameAnimation { //这里的KeyPath很重要,不要写错,keyPath后面跟的属性是CALayer的属性 CAKeyframeAnimation *keyFrameAnimation = [CAKeyframeAnimation animationWithKeyPath:@"position.x"]; //实现左右晃动效果 CGPoint position = self.greenView.layer.position; float left_x = position.x - 20; float right_x = position.x + 20; NSValue *leftValue = [NSValue valueWithCGPoint:CGPointMake(left_x, position.y)]; NSValue *rightValue = [NSValue valueWithCGPoint:CGPointMake(right_x, position.y)]; //元素位置 NSValue *orginalValue = [NSValue valueWithCGPoint:position]; //将所有的位置信息添加到数组 keyFrameAnimation.values = @[orginalValue,leftValue,rightValue]; //设置动画时长 keyFrameAnimation.duration = 0.1; //重复次数 keyFrameAnimation.repeatCount = 20; return keyFrameAnimation; [self.greenView.layer addAnimation:keyFrameAnimation forKey:@""]; } //阻尼动画 -(CASpringAnimation*)springAnimation { CASpringAnimation *spring = [CASpringAnimation animationWithKeyPath:@"transform.rotation"]; //质量,影响图层运动的弹簧惯性,质量越大幅度越大 spring.mass = 1; //刚度系数,越大形变产生的力就越大,运动越快 spring.stiffness = 0.5; spring.fromValue = @1; spring.toValue = @2; spring.repeatCount = 5; //初始速率 spring.initialVelocity = 5; //阻尼系数0~1,越大,停止越快 spring.damping = 0.2; //结算时间 spring.duration = spring.settlingDuration; return spring; } //组合动画,把上面三个动画放在一个group里 -(void)groupAnimation { CAAnimationGroup *group = [CAAnimationGroup animation]; group.animations = @[[self basicAnimation],[self layerKeyFrameAnimation],[self springAnimation]]; group.duration = 3; [self.greenView.layer addAnimation:group forKey:@""]; }