1 // 将视图作为属性方便后面执行多个不同动画 2 _myView = [[UIView alloc] init]; 3 _myView.layer.position = CGPointMake(100, 100); 4 _myView.layer.bounds = CGRectMake(0, 0, 100, 100); 5 _myView.backgroundColor = [UIColor blueColor]; 6 [self.view addSubview:_myView]; 7 [_myView release];
1 // 创建一个CABasicAnimation类型的动画对象并对CALayer的position属性执行动画 2 CABasicAnimation *anim = [CABasicAnimation animationWithKeyPath:@"position"]; 3 4 // 动画持续1.5s 5 anim.duration = 1.5; 6 7 // position属性值从(50, 80)渐变到(300, 350) 8 anim.fromValue = [NSValue valueWithCGPoint:CGPointMake(50, 80)]; 9 anim.toValue = [NSValue valueWithCGPoint:CGPointMake(300, 350)]; 10 11 // 设置动画的代理 12 anim.delegate = self; 13 14 // 保持动画执行后的状态 15 anim.removedOnCompletion = NO; 16 anim.fillMode = kCAFillModeForwards; 17 18 // 添加动画对象到myView的图层上 19 [_myView.layer addAnimation:anim forKey:@"translate"];
注意:可以尝试将第9行的toValue换成byValue 区别:前者是到指定的位置,后者是在当前的位置上增加多少。
fillMode的作用就是决定当前对象过了非active时间段的行为。比如动画开始之前,动画结束之后。如果是一个动画CAAnimation,则需要将其removedOnCompletion设置为NO,要不然fillMode不起作用.
kCAFillModeRemoved 默认值 也就是说当动画开始前和动画结束后,动画对layer都没有影响,动画结束后,layer会恢复到之前的状态
kCAFillModeForwards 当动画结束后,layer会一直保持着动画最后的状态
kCAFillModeBackwards 这个和kCAFillModeForwards是相对的,就是在动画开始前,你只要将动画加入了一个layer,layer便立即进入动画的初始状态并等待动画开始.你可以这样设定测试代码,将一个动画加入一个layer的时候延迟5秒执行.然后就会发现在动画没有开始的时候,只要动画被加入了layer,layer便处于动画初始状态
kCAFillModeBoth 理解了上面两个,这个就很好理解了,这个其实就是上面两个的合成.动画加入后开始之前,layer便处于动画初始状态,动画结束后layer保持动画最后的状态.
1 #pragma mark -----动画开始----- 2 - (void)animationDidStart:(CAAnimation *)anim { 3 NSLog(@"动画开始了"); 4 } 5 6 #pragma mark -----动画结束----- 7 - (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag { 8 // 查看一下动画执行完毕后的position值 9 NSString *string = NSStringFromCGPoint(_myView.layer.position); 10 NSLog(@"动画结束了,position:%@", string); 11 }
运行后发现, 在实质上,图层的属性值还是动画执行前的初始值,并没有真正被改变。
1 // 移除动画 2 [_myView.layer removeAnimationForKey:@"translate"]
1 CABasicAnimation *anim = [CABasicAnimation animationWithKeyPath:@"transform"]; 2 anim.duration = 1; 3 4 CATransform3D form = CATransform3DMakeTranslation(350, 350, 0); 5 anim.toValue = [NSValue valueWithCATransform3D:form]; 6 7 [_myView.layer addAnimation:anim forKey:nil];
1 CABasicAnimation *anim = [CABasicAnimation animationWithKeyPath:@"bounds"]; 2 anim.duration = 2; 3 4 anim.toValue = [NSValue valueWithCGRect:CGRectMake(0, 0, 30, 30)]; 5 6 [_myView.layer addAnimation:anim forKey:nil];
通过CALayer的bounds属性实现缩放动画,layer会从原来的尺寸(100x100)变为30x30
1 CABasicAnimation *anim = [CABasicAnimation 2 animationWithKeyPath:@"transform"]; 3 anim.duration = 1.5; // 动画持续1.5s 4 5 // CALayer的宽度从0.5倍变为2倍 6 // CALayer的高度从0.5倍变为1.5倍 7 anim.fromValue = [NSValue valueWithCATransform3D:CATransform3DMakeScale(0.5, 0.5, 1)]; 8 anim.toValue = [NSValue valueWithCATransform3D:CATransform3DMakeScale(2, 1.5, 1)]; 9 10 [_myView.layer addAnimation:anim forKey:nil];
1 CABasicAnimation *anim = [CABasicAnimation animationWithKeyPath:@"transform"]; 2 anim.duration = 1.5; 3 4 // 绕着(1, 1, 0)这个向量轴顺时针旋转45° 5 anim.toValue = [NSValue valueWithCATransform3D:CATransform3DMakeRotation(M_PI_4, 1, 1, 0)]; 6 7 [_myView.layer addAnimation:anim forKey:nil];
提示:如果要仅需要图形以2D的方式旋转,只要把CATransform3DMakeRotation在z方向上的值改为1即可。
anima.toValue=[NSValue valueWithCATransform3D:CATransform3DMakeRotation(M_PI_4, 1, 1, 0)];