您的位置:首页 > 移动开发 > IOS开发

iOS 动画

2016-03-03 10:47 330 查看
iOS中动画分为两类,UIView动画 和 CALayer动画

UIView动画可以给UIView的部分属性添加动画效果

支持动画的属性有:frame、center、bounds、alpha、transform、backgroundColor等;UIView动画也支持翻转或翻页动画效果:UIViewAnimationTransitionXXX;

UIView动画和CALayer动画比较:

UIView动画本质上也是CALayer动画;

通过UIView动画执行之后,UIView的相关属性已经真实改变;而CALayer动画默认在执行完毕后,会自动返回回去;并且执行完成后,即使设置动画fillMode不变后,为它设置的属性也并不会改变;

下面来看一个UIView动画实例

[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:2.5];
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromLeft forView:view cache:YES];
[UIView commitAnimations]; // 提交执行动画


在第一个方法中,第一个参数是指定该动画的名称,第二个参数在动画开始/结束的时候,会把这个参数给传过来;两个参数都可为空。

除此之外还有其它方法:

+ (void)setAnimationDelegate:(nullable id)delegate;
// 设置代理
+ (void)setAnimationWillStartSelector:(nullable SEL)selector;
// 单独指定Start监听
+ (void)setAnimationDidStopSelector:(nullable SEL)selector;
// 单独指定Stop监听
+ (void)setAnimationCurve:(UIViewAnimationCurve)curve;
// 设置渐变效果,默认是UIViewAnimationCurveEaseInOut
......


设置代理之后,实现UIViewController的以下两个方法

-(void)animationWillStart:(NSString *)animationID context:(void *)context // 开始
-(void)animDidStoped:(id)sender finished:(NSNumber *)finished  context:(void *)context // 结束


上面是使用[UIView animation___]的形式,实现UIView动画还可以通过Block的方式。

+ (void)animateWithDuration:(NSTimeInterval)duration
delay:(NSTimeInterval)delay
options:(UIViewAnimationOptions)options
animations:(void (^)(void))animations
completion:(void (^)(BOOL finished))completion


UIView只是一个矩形区域,真正负责显示渲染的是CALayer;

CALayer

iOS中的层类,是图形界面的基础,所有的界面元素都源自于它;

UIView中有一个readonly的属性就是layer;CALayer同样也有frame,bounds,backgroundColor等属性;如果一个控件是另一个控件的子控件,那么这个控件中的layer也是另外一个控件的子layer

可以通过UIView的layer属性,给视图添加阴影,边框等效果;

shadowOffset  // 阴影偏移量
shadowColor  // 阴影颜色
shadowOpacity  // 阴影透明度,默认为0
borderWidth  // 边框宽度
borderColor  // 边框颜色


CALayer特有的两个属性

anchorPoint // 锚点,默认是在视图的中心,值为(0.5,0.5),左上角为(1,1);
position  // position是锚点基于父视图原点的位置;


修改position,锚点不变,但frame会变化;

修改锚点,position不变,但frame会变化;

view.layer.borderWidth = 10;
view.layer.borderColor = [UIColor greenColor].CGColor;
view.layer.cornerRadius = 10;  // 圆角
view.layer.masksToBounds = YES; // 超出主图层的部分剪切掉;
view.clipsToBounds = YES;
view.layer.bounds = CGRectMake(0, 0, 100, 100);
view.layer.position = CGPointMake(100, 100);
// 设置的image不是展示在主图层上的,而是展示在子图层上的;
view.layer.contents = (id)[UIImage imageName:@"xxx"].CGImage;
view.layer.shadowColor;  // 阴影颜色
view.layer.shadowOffset = CGSizeMake(-10 ,0);  // 设置阴影偏移
view.layer.shadowOpacity;  // 阴影透明度,1:完全不透明


CALayer动画3种实现形式

view.layer.transform = CATransform3DMakeTranslation(0, 0, 100);
NSValue *v = [NSValue valueWithCATransform3D:CATransform3DMakeTranslation(0,-100,0)];
[view.layer setValue:v forKeyPath:@"transform"];
[view.layer setValue:@(100) forKeyPath:@"transform.translation.x"];


自定义CALayer

1.重写drawInContext方法,在此方法中给layer绘制图形,注意CALayer中的drawInContext方法,不会自动调用,只能通过setNeedsDisplay方法调用;

-(void)drawInContext:(ContextRef)ctx


2.另一个使用CALayer渲染的方法

layer.delegate = self;
// 在self这个对象中重写
drawLayer:(CALayer *)layer inContext:(ContextRef)ctx // 在该方法中进行渲染;


每个UIView内部都默认关联一个CALayer,这个Layer称为RootLayer,所有的非rootLayer,也就是手动创建的CALayer,都存在隐式动画,也就是当对这些非rootLayer的部分属性进行修改时,默认会自动附带动画效果;在UIView的头文件中,包含Animatable的属性都支持隐式动画;

<1>.关闭隐式动画

[CATransaction begin];
[CATransaction setDisableActions:YES];
[layer.bounds = CGRectMake(0, 0, 100, 100);  // 隐式动画;
[CATransaction commit];


CAAnimation

CAAnimation类中封装了iOS中所有的动画效果,动画是添加在Layer上的,(CoreAnimation是直接作用在CALayer上)是动画的触发核心,常见的有透明,飘浮,缩放;

CAAnimation类是抽象父类,它有三个子类:

CAPropertyAnimation
- CABasicAnimation
- CAKeyFrameAnimation
CAAnimationGroup
CATransition


其中CAPropertyAnimation又有两个子类,用来给CALayer的部分属性添加动画;

1.CABasicAnimation

keyPath;
fromValue;
toValue;
byValue;


keyPath就是CALayer中可以做动画的属性,比如position,对于position属性,它是一个结构体,这时候我们还可以继续指定keyPath为position.x;调用构造方法animationWithKeyPath:@”position.x”;与此同时,fromValue和toValue也要改为对应的keyPath对应的类型;

Example

CABasicAnimation *anim = [CABasicAnimation animation];
anim.keyPath = @"position";  // 设置需要发生动画的属性
anim.keyPath = @"bounds";  // toValue = [NSValue valueWithCGRect:CGRectMake(0, 0, 200, 200)];
anim.keyPath = @"transform";  // toValue = [NSValue valueWithCATransform3D:CATransform3DMakeRotation(PI, 0, 0, 1)];
anim.keyPath = @"transform.translation.y";  // toValue = @(100);
anim.fromValue;
anim.toValue;
anim.removedOnCompletion = NO;  // 设置动画执行完毕后不删除动画;
anim.fillMode = kCAFillModeForwards;  // 设置保存动画的最新状态;
[layer addAnimation:anim forKey:nils];  // 添加核心动画到layer;


2.CAKeyFrameAnimation

关键帧动画,某一属性按照一串数值来执行动画

anim.keyPath; // 同上
anim.values;
anim.keyTimes;  // 用于设置每一帧动画结束的时候占用总时长百分比;
anim.repeatCount;  // 重复次数;
anim.timimgFunction = [CAMediaTimingFunction functionWithName:...]; // 动画速率
anim.path;  // 帧动画还可以指定一个路径,让layer沿指定路径运动;路径对象为一个CGMutablePathRef对象实例(路径指定后需要手动release该路径);
delegate;
// 动画代理,指定为一个NSObject对象,NSObject对象中有两个方法animationDidStart 和animationDidStop,分别表示动画开始和动画结束;
[layer removeAnimationForKey:(NSString *)]; // 停止动画


Example

CAKeyframeAnimation *anim = [CAKeyframeAnimation animationWithKeyPath:@"position"];
NSArray *arr = [NSArray arrayWithObjects:[NSValue valueWithCGPoint:CGPointMake(100, 100)],
[NSValue valueWithCGPoint:CGPointMake(20, 20)],
[NSValue valueWithCGPoint:CGPointMake(200, 150)],
[NSValue valueWithCGPoint:CGPointMake(140, 210)],
[NSValue valueWithCGPoint:CGPointMake(200, 150)], nil];
anim.values = arr;
anim.keyTimes = [NSArray arrayWithObjects:[NSNumber numberWithFloat:0.1],
[NSNumber numberWithFloat:0.3],
[NSNumber numberWithFloat:0.4],
[NSNumber numberWithFloat:0.7],
[NSNumber numberWithFloat:1.0], nil];
anim.duration = 2;
[self.uiview.layer addAnimation:anim forKey:@""];


3.CATransition

主要用于提供一些过渡效果;

改变一个view的位置,角度等可以通过设置view.transform来实现;

CGAffineTransformMakeRotation
CGAffineTransformMakeScale
CGAffineTransformMakeTranslation


CGAffineTransformXXX:2D仿射变换,不属于动画,但是经常和动画配合使用,view上的每个点按照一定规律变化,可做出缩放,旋转,平移等效果;

[UIView beginAnimations:@"a" context:NULL];
[UIView setAnimationDuration:2];
self.uiview.transform = CGAffineTransformMakeScale(1.2, 1.7);
// self.uiview.transform = CGAffineTransformRotate(self.uiview.transform, M_PI / 4);
[UIView commitAnimations];


CATransition *anim = [CATransition animation];
anim.duration = 1.0;
anim.type = @"pageCurl";  // 动画过渡类型 | cube | kCATransitionMoveIn
anim.subtype = kCATransitionFromRight;  // 动画过渡方向
anim.delegate =; // 代理
[view.layer addAnimation:aim forKey:nil];


UIView执行Transition(转场)动画

[UIView transitionWithView:view duration:2.0 options:UIViewAnimationOptionsTransitionFlipFromLeft animations:^{
view.image = [UIImage imageNamed:@""];
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromRight forView:self.view cache:YES];
} completion:^(BOOL finished){
}]; // 旋转的同时切换图片


3D动画

view.layer.transform = CATransform3DMakeRotation(M_PI_2, 0, 1, 0); // 让view绕y轴旋转90度


4.CAAnimationGroup

CABasicAnimation *anim = [CABasicAnimation animationWithKeyPath:@"backgroundColor"];
anim.fromValue = (id)[UIColor redColor].CGColor;
anim.toValue = (id)[UIColor blueColor].CGColor;
anim.duration = 2;

CABasicAnimation *anim1 = [CABasicAnimation animationWithKeyPath:@"position.x"];
anim1.fromValue = (id)[NSNumber numberWithInt:100];
anim1.toValue = (id)[NSNumber numberWithInt:200];
anim1.duration = 2;

CAAnimationGroup * group = [CAAnimationGroup animation];
NSArray *arr = [NSArray arrayWithObjects:anim  ,anim1 , nil];
group.animations = arr;
group.duration = 3;
[self.uiview.layer addAnimation:group forKey:@""];


Transform:动画需要回到原始状态的时候使用该动画;

[UIView animationWithDuration:duration animations:^{
} completion:^(BOOL finished){
}];
[UIView animationWithDuration:duration delay:delay options:(UIViewAnimationOptions) animations:^{
} completion:^(BOOL finished){
}];
// 其中options选项常用如下
UIViewAnimationOptionCurveEaseInOut(开始由慢到快,结束由快到慢)
UIViewAnimationOptionCurveEaseIn(由慢到快)
UIViewAnimationOptionCurveEaseOut(由快到慢)
UIViewAnimationOptionCurveEaseLinear(线性)


关闭动画

[UIView setAnimationsEnabled:NO];  // 整个应用程序中的UIView动画都会失效;
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  ios 动画