iOS 动画

来源:互联网 发布:匡恩网络福利待遇 编辑:程序博客网 时间:2024/05/10 08:57

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  // 阴影透明度,默认为0borderWidth  // 边框宽度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  - CAKeyFrameAnimationCAAnimationGroupCATransition

其中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来实现;

CGAffineTransformMakeRotationCGAffineTransformMakeScaleCGAffineTransformMakeTranslation

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 | kCATransitionMoveInanim.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动画都会失效;
0 0
原创粉丝点击