原创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 |
确定view在superview的位置和大小,这里要注意,如果View的属性transform不是恒定的,修改位置和大小用bounds和center来修改。(其实一般修改位置和大小都不直接修改frame) |
bounds |
确定view的大小 |
center |
确定view的中心在superview的位置 |
transform |
2D仿射变换(scale,rotate,translate)3D变换要用到CALayer的Animation |
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