原创Blog,转载请注明出处
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的类方法来配置,动画在另一个线程上执行,不会阻塞主线程。
几个方法
配置动画开始执行的时间 | |
执行时间 | |
动画执行的加速减速过程 | |
设置重复次数以及是否自动返回 | |
用代理或者是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下载: