CoreAnimation详解(二)从UIKit的角度来详细阐述

原创Blog,转载请注明出处

blog.csdn.net/hello_hwc


UIKit是在Cocoa Touch层的,其底层仍然是通过Core Animation实现的,因此我把所有的动画讲解都放到了CoreAnimation这一块,

通常简单的动画用UIKit来实现足矣,当然,用Layer可以实现更加复杂的动画。不了解Layer的同学可以看看我前一篇文章。

本文将要讲述的内容:

1 可以用作Animation的属性

2 用基于block的方法来实现动画

3 用Begin/Commit方法来实现动画

4 View之间切换的动画

5 多个动画一起组成复杂的动画

6  View和Layer动画进行组合


还是老样子,我还是会写一个Demo,这个demo是基于一个tabbarViewController的,每个部分展示两个动画。下载链接附在最后。下面开始正文

视频的Demo链接(以防gif不会动)

http://v.youku.com/v_show/id_XODgzNDU3MDI0.html

一 可以用作Animation的属性

从UIKit的角度,动画是从UIView的属性变更来实现的。可以变换的属性如下

frame

确定viewsuperview的位置和大小,这里要注意,如果View的属性transform不是恒定的,修改位置和大小用boundscenter来修改。(其实一般修改位置和大小都不直接修改frame

bounds

确定view的大小

center

确定view的中心在superview的位置

transform

2D仿射变换(scalerotatetranslate3D变换要用到CALayerAnimation

alpha

透明度

backgroundColor

背景色

contentStretch

修改View拉伸来填充可以利用空间的方式


二 基于Block的方法

主要就是三个类方法,在动画的时候是在另一个线程上的,不会组赛主线程。

animateWithDuration:animations
animateWithDuration:animations:completion:
animateWithDuration:delay:options:animations:completion

简单介绍下各个参数:

    [UIView animateWithDuration: //动画持续时间
                          delay: //延迟多久执行
                       options://执行选项:例如动画的过程描述,动画过程是否允许交互等等,比较多,更多参见文档
                     animations:^{
                         //执行的动画的block
                     }
                     completion:^(BOOL finished) {
                         //动画结束后的block
                    }];

然后,定义一个动画,让imageview运动到中心,放大到之前的2倍,并且透明度变味0.5,结束后恢复原样。

效果如下gif。


实现代码,

 CGPoint oldCenter = self.imageivew.center;
    CGAffineTransform oldtransform = self.imageivew.transform;
    CGFloat oldAlpha = self.imageivew.alpha;
    
    [UIView animateWithDuration:2.0 //动画持续时间
                          delay:0.0 //延迟多久执行
    
                        options: UIViewAnimationOptionCurveEaseInOut | UIViewAnimationOptionBeginFromCurrentState //执行选项:例如动画的过程描述,动画过程是否允许交互等等,比较多,更多参见文档
                     animations:^{
                         //执行的动画的block
                         self.imageivew.center = self.view.center;
                         self.imageivew.transform = CGAffineTransformConcat(CGAffineTransformMakeRotation(M_PI), CGAffineTransformMakeScale(2.0, 2.0));
                         self.imageivew.alpha = 0.5;
                     }
                     completion:^(BOOL finished) {
                         //动画结束后的block
                         self.imageivew.center = oldCenter;
                         self.imageivew.transform = oldtransform;
                         self.imageivew.alpha = oldAlpha;
                     }];

三 基于Begin/commit的方式

也是UIView的类方法来配置,动画在另一个线程上执行,不会阻塞主线程。

几个方法

setAnimationStartDate:

setAnimationDelay:

配置动画开始执行的时间

setAnimationDuration:

执行时间

setAnimationCurve:

动画执行的加速减速过程

setAnimationRepeatCount:

setAnimationRepeatAutoreverses:

设置重复次数以及是否自动返回

setAnimationDelegate:

setAnimationWillStartSelector:

setAnimationDidStopSelector:

用代理或者是Selector来监听动画开始结束事件


 一个例子

效果和之前的类似,但是这次会逆向返回,执行1.5次

注意:这里我把大部分方法的使用方式都列上去了,正常情况下是不需要配置这么多的。


实现代码

- (IBAction)animate2:(id)sender {
    [UIView beginAnimations:@"Animate 2" context:nil];
    //配置动画的执行属性
    [UIView setAnimationDelay:0.5];//延迟时间
    [UIView setAnimationDelegate:self];
    [UIView setAnimationWillStartSelector:@selector(willStart)];//监听开始的事件
    [UIView setAnimationDidStopSelector:@selector(didStop)];//监听结束的事件
    [UIView setAnimationDuration:2.0];//执行时间
    [UIView setAnimationRepeatAutoreverses:YES];//自动复原
    [UIView setAnimationRepeatCount:1.5];//重复次数
    [UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];//执行的加速过程(加速开始,减速结束)
    [UIView setAnimationBeginsFromCurrentState:YES];//是否由当前动画状态开始执行(处理同一个控件上一次动画还没有结束,这次动画就要开始的情况)
    //实际执行的动画
    self.imageivew.center = self.view.center;
    self.imageivew.transform = CGAffineTransformConcat(CGAffineTransformMakeRotation(M_PI), CGAffineTransformMakeScale(2.0, 2.0));
    self.imageivew.alpha = 0.5;
    //提交动画
    [UIView commitAnimations];
}
-(void)willStart{
    NSLog(@"will start");
}
//这个有点问题
-(void)didStop{
        NSLog(@"did stop");
}

四 View之间的切换动画

比如添加删除subview的时候,比如让一个subview隐藏另一个显示的时候,加上切换动画能防止突变,造成用户困惑。

通常在view之间切换的时候,只是改变hidden以及remove或者add,这样的好处是系统会进行快照,来生成一副bitmap,占用资源较少。如果想要同时添加其他动画,要在函数的options里添加UIViewAnimationOptionAllowAnimatedContent

4.1 改变一个View的subview

有两种方式,通过block和通过begin/commit都可以实现。Demo实现的是两个不同动画,可以看到containView的不同,动画的差异。

动画一

用Flip的方式进行切换

效果


实现代码

    [UIView beginAnimations:@"AnimateInContainView" context:nil];
    [UIView setAnimationTransition:UIViewAnimationTransitionFlipFromLeft forView:self.containVIew cache:YES];
    [UIView setAnimationDuration:1.0];
    self.firstImageView.hidden = !self.firstImageView.hidden;
    self.secondImageView.hidden = !self.secondImageView.hidden;

动画二效果

用翻页的效果进行实现


实现代码

    [UIView transitionWithView:self.view
                      duration:1.0
                       options:UIViewAnimationOptionTransitionCurlUp
                    animations:^{
                        self.firstImageView.hidden = !self.firstImageView.hidden;
                        self.secondImageView.hidden = !self.secondImageView.hidden;
                    }
                    completion:^(BOOL finished) {
                        
                    }];

4.2 将一个View替代为一个新的view transitionFromView:toView:duration:options:completion:

这个函数会用toView来替换FrameView,FromView会被删除,如果只是想隐藏,要为options添加 UIViewAnimationOptionShowHideTransitionViews。

实现效果:

如果第一个imageView存在,则用第二个替换,反之亦然


代码:

 [UIView transitionFromView:(self.isFirstViewSHowing ? self.firstView : self.secondView)
                        toView:(self.isFirstViewSHowing ? self.secondView : self.firstView)
                      duration:1.0
                       options:(self.isFirstViewSHowing ? UIViewAnimationOptionTransitionFlipFromRight :
                                UIViewAnimationOptionTransitionFlipFromLeft)
                    completion:^(BOOL finished) {
                        if (finished) {
                            self.isFirstViewSHowing = !self.isFirstViewSHowing;
                        }
                    }];

五 动画组合

不管是用block还是begin/commit的方式,都可以监听动画结束的事件,那么一个动画结束的事件里开始另一个动画,动画就组合到一起了。

实现效果

初始状态:缩小到之前的0.2倍,完全透明

动画一:恢复正常大小,变成不透明

动画二:延迟2s,然后从左向右移除view


动画

 [self.view addSubview:self.firstView];
    self.firstView.center = self.view.center;
    self.firstView.transform = CGAffineTransformMakeScale(0.2,0.2);
    self.firstView.alpha = 0.0;
    self.animation6button.enabled = NO;
    [UIView animateWithDuration:1.0
                     animations:^{
                         self.firstView.transform = CGAffineTransformMakeScale(1.0, 1.0);
                         self.firstView.alpha = 1.0;
                     }
                     completion:^(BOOL finished) {
                         if (finished) {
                             [UIView animateWithDuration:1.0
                                                   delay:2.0
                                                 options:UIViewAnimationOptionCurveEaseIn
                                              animations:^{
                                                  self.firstView.center = CGPointMake(self.firstView.center.x + CGRectGetWidth(self.view.frame), self.firstView.center.y);
                                              }
                                              completion:^(BOOL finished) {
                                                  [self.firstView removeFromSuperview];
                                                  self.animation6button.enabled = YES;
                                              }];
                         }
                     }];

六 同CALayer的动画配合

不管是从UIkit还是从Layer的角度,底层都是Core Animation实现的,因此只要两个动画几乎同时提交的,那么动画的过程就是同时执行的。

实现效果

动画一:在layer的角度进行3D旋转,同时在view的角度把透明度变成0.2

动画二:用翻页的方式删除ImageView



代码

    [self.view addSubview:self.secondView];
    self.secondView.center = self.view.center;
    CABasicAnimation* layerAnimation = [CABasicAnimation animationWithKeyPath:@"transform"];
    layerAnimation.duration = 2.0;
    layerAnimation.timingFunction = [CAMediaTimingFunction
                                     functionWithName:kCAMediaTimingFunctionLinear];
    layerAnimation.toValue = [NSValue valueWithCATransform3D:CATransform3DMakeRotation(M_PI,1,1,1)];
    layerAnimation.removedOnCompletion = NO;
    layerAnimation.fillMode = kCAFillModeForwards;
    [self.secondView.layer addAnimation:layerAnimation forKey:@"layerAnimation"];
    [UIView animateWithDuration:2.0 animations:^{
        self.secondView.alpha = 0.2;
    } completion:^(BOOL finished) {
        [UIView transitionFromView:self.secondView
                            toView:nil
                          duration:1.0
                           options:UIViewAnimationOptionTransitionCurlUp
                        completion:^(BOOL finished) {
                            self.secondView = nil;
                        }];
    }];

最后,附上Demo的下载链接

CSDN下载:

http://download.csdn.net/detail/hello_hwc/8412927

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值