一、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");
}];
}
3.spring动画
这个文章说的比较明白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动画
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:@""];
}