每一个视图能显示出来,都是因为有layer存在。该对象有两个比较重要的属性:position和anchorPoint,第一个属性代表该视图相对于父控件的位置,第二个属性表示该视图上的哪个点会移动到对应的位置,它的取值范围是0到1.默认是0.5即视图中心。
在创建的继承自CALayer的类里重写- (void)drawInContext:(CGContextRef)ctx 方法
// 重写该方法, 在该方法中给layer上绘制图形 // 注意CALayer中的drawInContext方法, 不会自动调用 // 只能自己通过setNeedDisplay方法调用 - (void)drawInContext:(CGContextRef)ctx { // 1.绘制图形 CGContextAddEllipseInRect(ctx, CGRectMake(0, 0, 100, 100)); // [[UIColor redColor] set]; // 注意不能用UIKit框架中的类 CGContextSetRGBFillColor(ctx, 1, 0, 0, 1); // 1.渲染图形 CGContextFillPath(ctx); }
CALayer *myLayer = [CALayer layer]; myLayer.delegate = self; // 通过代理自定义layer - (void)drawLayer:(CALayer *)layer inContext:(CGContextRef)ctx { // 1.绘制图形 CGContextAddEllipseInRect(ctx, CGRectMake(0, 0, 50, 100)); CGContextSetRGBFillColor(ctx, 1, 0, 0, 1); // 1.渲染图形 CGContextFillPath(ctx); }
所有的非根layer都存在隐式动画。当对非根层的部分属性进行修改时,会自动带有动画。这称之为隐式动画。
- (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib. CALayer *layer = [CALayer layer]; layer.backgroundColor = [UIColor redColor].CGColor; layer.bounds = CGRectMake(0, 0, 100, 100); layer.anchorPoint = CGPointZero; [self.view.layer addSublayer:layer]; self.layer = layer; } - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { // 关闭隐式动画 // [CATransaction begin]; // [CATransaction setDisableActions:YES]; // 隐式动画 self.layer.backgroundColor = [UIColor greenColor].CGColor; // self.layer.bounds = CGRectMake(0, 0, 200, 200); self.layer.position = CGPointMake(200, 200); // self.layer.position // 如何查看CALayer的某个属性是否支持隐式动画, 查看头文件是否有 Animatable // [CATransaction commit]; }
它是一个跨平台的,该动画不会阻塞主线程,在后台操作
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { // 1. 创建核心动画 CABasicAnimation *anima = [CABasicAnimation animation] ; // 1.1设置动画类型 // anima.keyPath = @"transform.translation.x"; anima.keyPath = @"transform.scale.y"; // 1.2 设置动画执行完毕之后不删除动画 anima.removedOnCompletion = NO; // 1.3 设置保存动画的最新状态 anima.fillMode = kCAFillModeForwards; // 1.4设置动画时间 anima.duration = 1; // 1.5如何动画 // anima.toValue = [NSValue valueWithCATransform3D:CATransform3DMakeTranslation(0, 100, 1)]; // anima.toValue = @(100); anima.toValue = @(1.5); // 2.添加核心动画到Layer [self.myLayer addAnimation:anima forKey:nil]; }
- (void)test1 { // 1.创建核心动画 CAKeyframeAnimation *keyAnima = [CAKeyframeAnimation animation]; // 1.1告诉系统执行什么动画 keyAnima.keyPath = @"position"; CGMutablePathRef path = CGPathCreateMutable(); CGPathAddEllipseInRect(path, NULL, CGRectMake(0, 100, 200, 200)); keyAnima.path = path; CGPathRelease(path); // 1.2保存执行完之后的状态 // 1.2.1执行完之后不删除动画 keyAnima.removedOnCompletion = NO; // 1.2.2执行完之后保存最新的状态 keyAnima.fillMode = kCAFillModeForwards; // 1.3设置动画时间 keyAnima.duration = 2; // 2.观察动画什么时候开始执行, 以及什么时候执行完毕 keyAnima.delegate = self; // 3.添加核心动画 [self.customView.layer addAnimation:keyAnima forKey:@"abc"]; }
- (void)test { // 1.创建核心动画 CAKeyframeAnimation *keyAnima = [CAKeyframeAnimation animation]; // 1.1告诉系统执行什么动画 keyAnima.keyPath = @"position"; // NSValue *v1 = [NSValue valueWithCGPoint:CGPointMake(0, 100)]; NSValue *v2 = [NSValue valueWithCGPoint:CGPointMake(100, 100)]; NSValue *v3 = [NSValue valueWithCGPoint:CGPointMake(100, 200)]; NSValue *v4 = [NSValue valueWithCGPoint:CGPointMake(0, 200)]; NSValue *v5 = [NSValue valueWithCGPoint:CGPointMake(0, 100)]; keyAnima.values = @[v2, v3, v4, v5]; //用来设置每一小段动画的时间 // keyAnima.keyTimes = @[@(0.5) ,@(0.5), @(0.5)]; keyAnima.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]; // 1.2保存执行完之后的状态 // 1.2.1执行完之后不删除动画 keyAnima.removedOnCompletion = NO; // 1.2.2执行完之后保存最新的状态 keyAnima.fillMode = kCAFillModeForwards; // 1.3设置动画时间 keyAnima.duration = 2; // 2.观察动画什么时候开始执行, 以及什么时候执行完毕 keyAnima.delegate = self; // 2.添加核心动画 [self.customView.layer addAnimation:keyAnima forKey:nil]; }可以实现动画的代理方法来看动画什么时候执行,什么时候执行结束
#define angle2Radian(angle) ((angle) / 180.0 * M_PI)
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { // 1.创建核心动画 CAKeyframeAnimation *keyAnima = [CAKeyframeAnimation animation]; keyAnima.keyPath = @"transform.rotation"; // 度数 / 180 * M_PI keyAnima.values = @[@(-angle2Radian(4)), @(angle2Radian(4)), @(-angle2Radian(4))]; keyAnima.removedOnCompletion = NO; keyAnima.fillMode = kCAFillModeForwards; keyAnima.duration = 0.1; // 设置动画重复的次数 keyAnima.repeatCount = MAXFLOAT; // 2.添加核心动画 [self.iconView.layer addAnimation:keyAnima forKey:nil]; }
// 1.创建核心动画 CATransition *ca = [CATransition animation]; // 1.1动画过渡类型 ca.type = @"cube"; // 1.2动画过渡方向 ca.subtype = kCATransitionFromRight; // 1.3动画起点(在整体动画的百分比) // ca.startProgress = 0.5; ca.endProgress = 0.5; // 动画时间 ca.duration = 1; // 2.添加核心动画 [self.iconView.layer addAnimation:ca forKey:nil];
/* 过渡效果
fade //交叉淡化过渡(不支持过渡方向) kCATransitionFade
push //新视图把旧视图推出去 kCATransitionPush
moveIn //新视图移到旧视图上面 kCATransitionMoveIn
reveal //将旧视图移开,显示下面的新视图 kCATransitionReveal
cube //立方体翻滚效果
oglFlip //上下左右翻转效果
suckEffect //收缩效果,如一块布被抽走(不支持过渡方向)
rippleEffect //滴水效果(不支持过渡方向)
pageCurl //向上翻页效果
pageUnCurl //向下翻页效果
cameraIrisHollowOpen //相机镜头打开效果(不支持过渡方向)
cameraIrisHollowClose //相机镜头关上效果(不支持过渡方向)
*/
/* 过渡方向
kCATransitionFromRight
kCATransitionFromLeft
kCATransitionFromBottom
kCATransitionFromTop*/
CATransition*anim = [CATransition animation];
anim.type =@“cube”; // 动画过渡类型
anim.subtype =kCATransitionFromTop; // 动画过渡方向
anim.duration =1; // 动画持续1s
//代理,动画执行完毕后会调用delegate的animationDidStop:finished:
anim.delegate= self;
/*******中间穿插改变layer属性的代码**********/
[layeraddAnimation:anim forKey:nil];
// 平移动画 CABasicAnimation *a1 = [CABasicAnimation animation]; a1.keyPath = @"transform.translation.y"; a1.toValue = @(100); // 缩放动画 CABasicAnimation *a2 = [CABasicAnimation animation]; a2.keyPath = @"transform.scale"; a2.toValue = @(0.0); // 旋转动画 CABasicAnimation *a3 = [CABasicAnimation animation]; a3.keyPath = @"transform.rotation"; a3.toValue = @(M_PI_2); // 组动画 CAAnimationGroup *groupAnima = [CAAnimationGroup animation]; groupAnima.animations = @[a1, a2, a3]; groupAnima.duration = 2; groupAnima.fillMode = kCAFillModeForwards; groupAnima.removedOnCompletion = NO; [self.iconView.layer addAnimation:groupAnima forKey:nil];
[UIView transitionWithView:self.view duration:1.0 options:0 animations:^{ NSLog(@"animations"); // 要执行的动画 [UIView setAnimationTransition:UIViewAnimationTransitionFlipFromRight forView:self.view cache:YES]; } completion:^(BOOL finished) { NSLog(@"completion"); // 执行完毕之后执行的动画 }];