iOS动画小结

动画总结

前言

在iOS开发中,如果遇到稍微复杂的交互,就不知道如何去实现这个效果,加上iOS动画又非常的庞杂,总是让你眼花缭乱。如果平时不注重总结和分类,到用的时候还真是不知道从哪里下手。所有今天把平时在项目中用的动画分类总结一下。

直接使用UIView封装好的动画

UIView 动画本质是对CoreAnimation的封装,因为它提供了简洁而且高效的接口。可以用来用作动画的属性有:

  1. 大小的变化(frame)
  2. 拉伸的变化(bounds)
  3. 中心位置(center)
  4. 旋转(transform)
  5. 透明度(alpha)
  6. 背景颜色(backgroundcolor)

这类动画平时在项目中用的是最多的,可以基本满足一般的动画效果。废话不多说直接贴一段最近项目中使用的一段代码,实现的效果很简单就是透明度的变化及背景变化。项目启动时调用此方法
#pragma mark - 开始动画
- (void)startAnimation{

UIViewController *tempVC = [[UIViewController alloc] init];
tempVC.view.backgroundColor = [UIColor whiteColor];
self.window.rootViewController = tempVC;


UIImageView *imgView1 = [[UIImageView alloc]initWithImage:[UIImage imageNamed:@"animation1.jpg"]];

imgView1.frame = self.window.frame;
[tempVC.view addSubview:imgView1];



UIImageView *imgView2 = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"animation2.jpg"]];
imgView2.frame = self.window.frame;
imgView2.alpha = 0;
[tempVC.view addSubview:imgView2];

[UIView animateWithDuration:3.0 delay:0 options:UIViewAnimationOptionCurveEaseIn animations:^{
    imgView1.alpha = 0;//简单的透明度动画
} completion:^(BOOL finished) {

}];

[UIView animateWithDuration:2.0 delay:1 options:UIViewAnimationOptionCurveEaseIn animations:^{
    imgView2.alpha = 1;

} completion:^(BOOL finished) {

    [imgView2 removeFromSuperview];
    sleep(2);
    if ([[SendIFAPPDefault shareAppDefault].isFirstLanuch intValue] == 0) {

    //动画完成后处理逻辑
    }else{


    }

}];

}

这类动画别的属性就不一一举例了,以此类推。

转场动画

这类动画是在切换页面时,可以加个过度效果,说到转场动画就要说到CATransition这个类了。还是先贴代码主要的属性再仔细说下。

CATransition *animation = [CATransition animation];
[animation setDuration:1.25f];
[animation setTimingFunction:[CAMediaTimingFunction
functionWithName:kCAMediaTimingFunctionEaseIn]];
[animation setType:kCATransitionReveal];
[animation setSubtype: kCATransitionFromBottom];
[self.view.layer addAnimation:animation forKey:@"Reveal"];

需要注意的地方就是,typesubtype,因为这两个属性决定了转场的效果。先来看看这两个属性都有哪些值

type

Fade = 1,                   //淡入淡出
Push,                       //推挤
Reveal,                     //揭开
MoveIn,                     //覆盖
Cube,                       //立方体
SuckEffect,                 //吮吸
OglFlip,                    //翻转
RippleEffect,               //波纹
PageCurl,                   //翻页
PageUnCurl,                 //反翻页
CameraIrisHollowOpen,       //开镜头
CameraIrisHollowClose,      //关镜头
CurlDown,                   //下翻页
CurlUp,                     //上翻页
FlipFromLeft,               //左翻转
FlipFromRight,              //右翻转

subType

kCATransitionFromLeft
kCATransitionFromRight
kCATransitionFromTop
kCATransitionFromBottom
kCATruncationMiddle

简单的从单词来看就知道这个属性是控制效果方向的
最后再啰嗦一句,这个效果是作用于CALayer上的,直接添加在view上是没有任何效果的

CoreAnimation(核心动画)

如果一个效果十分复杂,前面介绍的动画实现起来困难或者实现不了,这个时候就需要用Layer动画了,既然提到Layer,这类的动画肯定是作用于layer上了。先来看看Layer都有哪些属性。如果属性都不清楚,当然效果也是做不出来的

  • bounds 和UIview一样,都有这个属性
  • position 默认为中点,和UIview的center一致
  • anchorPoint x,y的范围都是0到1
  • backgroundColor 这个背景颜色是CGColorRef 类型
  • transform 形变属性(2D,3D)

如果对postion和anchorPoint 有疑惑的话可以点击这里
前面的属性跟UIView差不多,就把这个transform简单的说下吧
动画效果包括平移,旋转和缩放

2D效果
这类是作用于UIview上的

CGAffineTransform CGAffineTransformMakeTranslation(CGFloat       tx, CGFloat ty) 

CGAffineTransform CGAffineTransformMakeScale(CGFloat sx,         CGFloat sy)   

CGAffineTransform CGAffineTransformMakeRotation(CGFloat          angle)

3D效果
这类是作用于layer上的

CATransform3D CATransform3DMakeRotate (CATransform3D t,          CGFloat angle, CGFloat     x, CGFloat y, CGFloat z);//旋转

CATransform3D CATransform3DMakeScale (CATransform3D t,           CGFloat sx, CGFloat sy, CGFloat sz) //缩放

CATransform3D CATransform3DMakeTranslation (CGFloat tx,          CGFloat ty, CGFloat tz) //平移
基础动画

CABasicAnimation是CAPropertyAnimation的子类,CAPropertyAnimation有一个字符串类型的keyPath属性.还是简单的放个例子吧

CABasicAnimation *anim = [CABasicAnimation animationWithKeyPath:@"transform"];
anim.duration = 1.5; // 动画持续1.5s

// CALayer的宽度从0.5倍变为2倍
// CALayer的高度从0.5倍变为1.5倍
anim.fromValue = [NSValue valueWithCATransform3D:CATransform3DMakeScale(0.5, 0.5, 1)];
anim.toValue  = [NSValue valueWithCATransform3D:CATransform3DMakeScale(2, 1.5, 1)];

[_myView.layer addAnimation:anim forKey:nil];

基础动画最重要的就是指定一个keypath,因为这个keypath是个单纯的字符串,写代码时也不会提示有什么作用于动画。用的时候很不方便,这里我贴出平时逛博客记录的一些属性,算是比较全了

transform.scale = 缩放

transform.scale.x = x轴缩放

transform.scale.y = y轴上缩放

transform.rotation.z = 旋转

opacity = 透明度

margin

zPosition

backgroundColor    背景颜色

cornerRadius    圆角

borderWidth

bounds

contents

contentsRect

cornerRadius

frame

hidden

mask

masksToBounds

opacity

position

shadowColor

shadowOffset

shadowOpacity

shadowRadius
关键帧动画

所谓关键帧动画,就是给需要动画效果的属性,准备一组与时间相关的值,这些值都是在动画序列中比较关键的帧中提取出来的,而其他时间帧中的值,可以用这些关键值,采用特定的插值方法计算得到,从而达到比较流畅的动画效果。废话不啰嗦,直接贴项目中用到的一处。基于MBHUB自定义网络提示动画

UIView *custom = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 100, 100)];
custom.backgroundColor = [UIColor purpleColor];
custom.layer.cornerRadius = 10;
custom.layer.masksToBounds = YES;
custom.backgroundColor = [UIColor colorWithRed:231.0/255 green:215.0/255 blue:198.0/255 alpha:1.0];
UIImageView *smallTop = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"icon_loading_02"]];
smallTop.frame = CGRectMake((custom.bounds.size.width-48)/2, 20, 48, 48);
[custom addSubview:smallTop];
UIImageView *bigImg = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"icon_loading_01"]];
bigImg.frame = CGRectMake((custom.bounds.size.width-48)/2, 20, 48, 48);
[custom addSubview:bigImg];
UILabel *warnLab = [[UILabel alloc] initWithFrame:CGRectMake(0, CGRectGetMaxY(bigImg.frame), custom.bounds.size.width, 15)];
warnLab.text = @"努力加载中...";
warnLab.textAlignment = NSTextAlignmentCenter;
warnLab.font = [UIFont systemFontOfSize:12];
[custom addSubview:warnLab];

//圆周运动
CGRect boundingRect = CGRectMake(-1, -1, 2, 2);
CAKeyframeAnimation *orbit = [CAKeyframeAnimation animation];
orbit.keyPath = @"position";
orbit.path = CFAutorelease(CGPathCreateWithEllipseInRect(boundingRect, NULL));
orbit.duration = 4;
orbit.additive = YES;
orbit.repeatCount = HUGE_VALF;
orbit.calculationMode = kCAAnimationPaced;
orbit.rotationMode = kCAAnimationRotateAuto;
[smallTop.layer addAnimation:orbit forKey:@"oribit"];


MBProgressHUD *hub = [MBProgressHUD showHUDAddedTo:[[UIApplication sharedApplication] keyWindow] animated:YES];
hub.mode = MBProgressHUDModeCustomView;
hub.dimBackground = NO;
hub.color = [UIColor clearColor];
hub.customView = custom;
return hub;

关键帧还有个很重要的属性Path,它是CGPathRef类型。配合CAShapelayer,UIBezierPath可以实现很复杂的动画,这里就不再举例了。

动画组

顾名思义,就是可以将几个或多个动画效果放在一起的类,具体使用请看下面列子
//动画组
CAAnimationGroup *animGroup = [CAAnimationGroup animation];

animGroup.animations = [NSArray arrayWithObjects:posAnim,        scaleAnim, opacityAnim, nil];

animGroup.duration = 1;
[imgView.layer addAnimation:animGroup forKey:nil];

对,就是这个animations属性,是一个数组类型,将各个简单的基本的动画放在一起就可以实现一些复杂的效果。

最后

再复杂的动画也都是基于上面的介绍的基本动画组成。遇到复杂的交互时,要善于去拆分,然后将基本的动画一一实现,然后再组合,就是实现了那些很炫很酷的动画效果了。


附 资源