IOS核心动画
2015-12-11 20:17
447 查看
核心动画
原码:
代码下载请猛戳这里!核心动画
1.CABasicAnimation:基础动画
- (void)basicAnimation:(CALayer *)layer { //1.创建动画对象 CABasicAnimation *animation = [CABasicAnimation animation]; //2.设置动画对象 /* keyPath:决定执行怎样的动画,调整哪个属性来执行动画。 fromValue:属性值丛什么值开始执行动画。 toValue:属性值到达什么值结束动画。 byVale:属性值增加了多少值之后结束动画。 duration:动画持续时间。 注意:以下两个属性结合起来用能让图层保持动画结束后的状态。 removedOnCompletion:执行完动画后是否移除该动画。 fillMode:动画保持的状态。 fillMode的作用就是决定当前对象过了非active时间段的行为. 比如动画开始之前,动画结束之后。如果是一个动画CAAnimation,则需要将其removedOnCompletion设置为NO,要不然fillMode不起作用. fillMode取值: 1.kCAFillModeRemoved: 这个是默认值,也就是说当动画开始前和动画结束后,动画对layer都没有影响,动画结束后,layer会恢复到之前的状态 。 2.kCAFillModeForwards: 当动画结束后,layer会一直保持着动画最后的状态 3.kCAFillModeBackwards: 这个和kCAFillModeForwards是相对的,就是在动画开始前,你只要将动画加入了一个layer,layer便立即进入动画的初始状态并等待动画开始.你可以这样设定测试代码,将一个动画加入一个layer的时候延迟5秒执行.然后就会发现在动画没有开始的时候,只要动画被加入了layer,layer便处于动画初始状态 4.kCAFillModeBoth: 理解了上面两个,这个就很好理解了,这个其实就是上面两个的合成.动画加入后开始之前,layer便处于动画初始状态,动画结束后layer保持动画最后的状态. */ CGFloat tabbar_height = 49; switch ([self.layers indexOfObject:layer]) { case 0: animation.keyPath = @"position"; animation.fromValue = [NSValue valueWithCGPoint:self.view.center]; animation.toValue = [NSValue valueWithCGPoint:CGPointMake(Main_Screen_With/3/2, Main_Screen_Height - Main_Screen_With/3/2 - tabbar_height)]; break; case 1: animation.keyPath = @"transform.translation.y"; animation.fromValue = [NSNumber numberWithFloat:0]; animation.toValue = [NSNumber numberWithFloat:Main_Screen_Height - Main_Screen_With/3 - tabbar_height]; break; case 2: animation.keyPath = @"transform.translation"; animation.fromValue = [NSValue valueWithCGPoint:CGPointMake(0, 0)]; animation.toValue = [NSValue valueWithCGPoint:CGPointMake(0, Main_Screen_Height - Main_Screen_With/3 - tabbar_height)]; break; case 3: animation.keyPath = @"bounds"; animation.fromValue = [NSValue valueWithCGRect:CGRectMake(0, 0, Main_Screen_With/3, Main_Screen_With/3)]; animation.toValue = [NSValue valueWithCGRect:CGRectMake(0, 0, Main_Screen_With/3, -Main_Screen_With/3/5)]; break; case 4: animation.keyPath = @"transform"; animation.byValue = [NSValue valueWithCATransform3D:CATransform3DMakeRotation(M_PI_2, 1, 1, 0)]; break; default: break; } animation.duration = 2; animation.delegate = self; animation.removedOnCompletion = NO; animation.fillMode = kCAFillModeForwards; //3.添加动画 [layer addAnimation:animation forKey:nil]; }
2.CAKeyframeAnimation:帧动画
- (void)keyFromAnimationInView:(UIView *)view andTapCount:(NSInteger)count { //1.创建动画 CAKeyframeAnimation *animation = [CAKeyframeAnimation animation]; //2.设置动画属性 /* values:指明整个动画过程中的关键帧点,需要注意的是,起点必须作为values的第一个值。 keyTimes:该属性是一个数组,用以指定每个子路径(AB,BC,CD)的时间。如果你没有显式地对keyTimes进行设置,则系统会默认每条子路径的时间为:ti=duration/(5-1),即每条子路径的duration相等,都为duration的1\4。当然,我们也可以传个数组让物体快慢结合。例如,你可以传入{0.0, 0.1,0.6,0.7,1.0},其中首尾必须分别是0和1,因此tAB=0.1-0, tCB=0.6-0.1, tDC=0.7-0.6, tED=1-0.7..... path:动画运动的路径。 repeatCount:动画重复次数。 timingFunctions:这个属性用以指定时间函数,控制动画节奏,类似于运动的加速度,有以下几种类型。记住,这是一个数组,你有几个子路径就应该传入几个元素 属性值描述: 1 kCAMediaTimingFunctionLinear//线性 4000 2 kCAMediaTimingFunctionEaseIn//淡入 3 kCAMediaTimingFunctionEaseOut//淡出 4 kCAMediaTimingFunctionEaseInEaseOut//淡入淡出 5 kCAMediaTimingFunctionDefault//默认 calculationMode:该属性决定了物体在每个子路径下是跳着走还是匀速走,跟timeFunctions属性有点类似 属性值描述: 1 const kCAAnimationLinear//线性,默认 2 const kCAAnimationDiscrete//离散,无中间过程,但keyTimes设置的时间依旧生效,物体跳跃地出现在各个关键帧上 3 const kCAAnimationPaced//平均,keyTimes跟timeFunctions失效 4 const kCAAnimationCubic//平均,同上 5 const kCAAnimationCubicPaced//平均,同上 */ animation.delegate = self; switch (count) { case 1: { animation.keyPath = @"position"; CGPoint centerP = self.view.center; CGFloat L = [UIScreen mainScreen].bounds.size.width - 100; NSValue *value1 = [NSValue valueWithCGPoint:centerP]; NSValue *value2 = [NSValue valueWithCGPoint:CGPointMake(centerP.x - L/2, centerP.y - L/2)]; NSValue *value3 = [NSValue valueWithCGPoint:CGPointMake(centerP.x + L/2, centerP.y - L/2)]; NSValue *value4 = [NSValue valueWithCGPoint:CGPointMake(centerP.x + L/2, centerP.y + L/2)]; NSValue *value5 = [NSValue valueWithCGPoint:CGPointMake(centerP.x - L/2, centerP.y + L/2)]; NSValue *value6 = [NSValue valueWithCGPoint:CGPointMake(centerP.x - L/2, centerP.y - L/2)]; NSValue *value7 = [NSValue valueWithCGPoint:centerP]; animation.values = @[value1,value2,value3,value4,value5,value6,value7]; //animation.keyTimes = @[@(0),@(0.1),@(0.3),@(0.5),@(0.7),@(0.9),@(1)]; animation.duration = 5; animation.timingFunctions = @[[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn],[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear],[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear],[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear],[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear],[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]]; } break; case 2: { animation.keyPath = @"position"; CGMutablePathRef path = CGPathCreateMutable(); CGFloat main_screen_w = [UIScreen mainScreen].bounds.size.width; CGFloat main_screen_h = [UIScreen mainScreen].bounds.size.height; CGFloat view_w = 100; CGPathAddEllipseInRect(path, NULL, CGRectMake(view_w/2, view_w/2, main_screen_w - view_w, main_screen_h - view_w - 49)); animation.path = path; CGPathRelease(path); animation.duration = 10; animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]; } break; case 3: { animation.keyPath = @"transform.rotation.z"; animation.values = @[@(0),@(M_PI_4),@(-M_PI_4),@(0)]; animation.timingFunctions = @[[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut],[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut],[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn]]; animation.duration = 2; animation.repeatCount = MAXFLOAT; } break; default: break; } animation.removedOnCompletion = NO; animation.fillMode = kCAFillModeForwards; //3.添加动画到图层 [view.layer addAnimation:animation forKey:nil]; }
3.CATransition:过度动画
- (IBAction)swipeGestureAction:(UISwipeGestureRecognizer *)sender { NSString *picName; CATransition *animation = [CATransition animation]; /* 转场动画 动画属性: type:执行什么样的动画。 属性取值: fade //交叉淡化过渡(不支持过渡方向) kCATransitionFade push //新视图把旧视图推出去 kCATransitionPush moveIn //新视图移到旧视图上面 kCATransitionMoveIn reveal //将旧视图移开,显示下面的新视图 kCATransitionReveal cube //立方体翻滚效果 oglFlip //上下左右翻转效果 suckEffect //收缩效果,如一块布被抽走(不支持过渡方向) rippleEffect //滴水效果(不支持过渡方向) pageCurl //向上翻页效果 pageUnCurl //向下翻页效果 cameraIrisHollowOpen //相机镜头打开效果(不支持过渡方向) cameraIrisHollowClose //相机镜头关上效果(不支持过渡方向) startProgress:动画从什么时候开始(相对于整个动画过程) endProgress:动画从什么时候结束(相对于整个动画过程) subType:动画的方向 kCATransitionFromRight:从右边 kCATransitionFromLeft:从左边 kCATransitionFromBottom:从底部 kCATransitionFromTop:从上边 */ if (sender.direction == UISwipeGestureRecognizerDirectionRight) { self.pageNumber --; if (self.pageNumber < 0) { self.pageNumber = 8; } picName = [NSString stringWithFormat:@"%i.jpg",abs(self.pageNumber + 1)]; animation.type = @"pageUnCurl"; //animation.subtype = kCATransitionFromRight; animation.duration = 0.5; } else if (sender.direction == UISwipeGestureRecognizerDirectionLeft) { self.pageNumber ++; if (self.pageNumber > 8) { self.pageNumber = 0; } picName = [NSString stringWithFormat:@"%i.jpg",self.pageNumber + 1]; animation.type = @"pageCurl"; animation.subtype = kCATransitionFromBottom; animation.duration = 0.5; } self.imageView.image = [UIImage imageNamed:picName]; [self.imageView.layer addAnimation:animation forKey:nil]; }
4.CAAnimationGroup:组动画
- (void)groupAnimation { //1.创建组动画 CAAnimationGroup *group = [CAAnimationGroup animation]; //2.将其他动画加入组动画中 group.animations = @[[self creatOpacityAnimation],[self creatKeyfromAnimation]]; group.duration = 0.5; group.removedOnCompletion = NO; group.fillMode = kCAFillModeForwards; //1.将动画组添加到图层上 [self.button.layer addAnimation:group forKey:nil]; } - (CABasicAnimation *)creatOpacityAnimation { CABasicAnimation *animation = [CABasicAnimation animation]; animation.keyPath = @"opacity"; animation.fromValue = @(0); animation.toValue = @(1); return animation; } - (CAKeyframeAnimation *)creatKeyfromAnimation { CAKeyframeAnimation *animation = [CAKeyframeAnimation animation]; animation.keyPath = @"position"; CGMutablePathRef path = CGPathCreateMutable(); CGPathAddArc(path, NULL, self.view.center.x + 50, self.view.center.y, 50, M_PI, 0, YES); animation.path = path; return animation; }
5.View动画
//核心动画都是假象,并没有改变真实的属性。 [UIView transitionWithView:self.view duration:0.5 options:UIViewAnimationOptionTransitionCurlUp animations:^{ self.index ++; if (self.index > 8) { self.index = 0; } self.imageVIew.image = [UIImage imageNamed:[NSString stringWithFormat:@"%i.jpg",(int)self.index + 1]]; } completion:nil];
相关文章推荐
- 峰回路转,Firefox 浏览器即将重返 iOS 平台
- 峰回路转,Firefox 浏览器即将重返 iOS 平台
- 不可修补的 iOS 漏洞可能导致 iPhone 4s 到 iPhone X 永久越狱
- iOS 12.4 系统遭黑客破解,漏洞危及数百万用户
- 每日安全资讯:NSO,一家专业入侵 iPhone 的神秘公司
- [转][源代码]Comex公布JailbreakMe 3.0源代码
- Gifski:一个跨平台的高质量 GIF 编码器
- 模仿动画的放大缩小容器
- jQuery 1.9.1源码分析系列(十五)动画处理之缓动动画核心Tween
- Android中ViewFlipper的使用及设置动画效果实例详解
- jQuery实现美观的多级动画效果菜单代码
- php判断GIF图片是否为动画的方法
- jQuery实现动画效果circle实例
- 浅析JavaScript动画
- js排序动画模拟-插入排序
- javascript+HTML5的Canvas实现Lab单车动画效果
- 基于javascript实现漂亮的页面过渡动画效果附源码下载
- js实现按钮颜色渐变动画效果
- jQuery实现连续动画效果实例分析