layer的核心动画的基本属性

本文深入介绍了iOS开发中CALayer的基本概念与属性,并详细解析了如何利用Core Animation实现丰富的动画效果,包括基本动画、关键帧动画及组合动画等。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

CALayer的简单介绍

1.UIView 是calyer的代理
2. 简单介绍
、简单介绍

在iOS中,你能看得见摸得着的东西基本上都是UIView,比如一个按钮、一个文本标签、一个文本输入框、一个图标等等,这些都是UIView。

其实UIView之所以能显示在屏幕上,完全是因为它内部的一个图层,在创建UIView对象时,UIView内部会自动创建一个图层(即CALayer对象),通过UIView的layer属性可以访问这个层

@property(nonatomic,readonly,retain) CALayer *layer; 

当UIView需要显示到屏幕上时,会调用drawRect:方法进行绘图,并且会将所有内容绘制在自己的图层上,绘图完毕后,系统会将图层拷贝到屏幕上,于是就完成了UIView的显示


换句话说,UIView本身不具备显示的功能,拥有显示功能的是它内部的图层。

3.CALayer的基本属性
代码如下

   
// 控制器的view的颜色
   
self.view.backgroundColor = [UIColor lightGrayColor];
   
//设置view1的位置和大小
   
UIView* view1 = [[UIView alloc] initWithFrame:CGRectMake(100, 100, 100, 100)];
   
//设置View1的背景颜色
    view1.
backgroundColor = [UIColor redColor];

   
// 1>边框
    view1.
layer.borderWidth = 10;
    view1.
layer.borderColor = [UIColor whiteColor].CGColor;//边框的颜色

   
// 2>阴影
    view1.
layer.shadowColor = [UIColor blueColor].CGColor;//阴影的颜色
   
//    view1.layer.shadowOffset = CGSizeMake(50, 50);
    view1.
layer.shadowOpacity = 1;//向同于alpah 透明度
   
    view1.
layer.shadowRadius = 50; //设置圆角,越大越模糊

   
// 3>圆角
    view1.
layer.cornerRadius = 50;//设置圆角图片
    view1.
layer.masksToBounds = YES;//剪切

   
// 4>bounds
    view1.
layer.bounds = CGRectMake(0, 0, 200, 200);//layer的大小

   
// 5>postion属性和view.center的关系(默认情况下)
    view1.
layer.position = CGPointMake(100, 100);//位置

   
// 6>设置内容(图片)
    view1.
layer.contents = (__bridge id)([UIImage imageNamed:@"me"].CGImage);

   
// 7>获取图片*

    [self.view addSubview:view1];//添加
4.手动创建layer
代码如下:
    // 创建layer对象
   
CALayer* layer = [[CALayer alloc] init];
   

    layer.
bounds = CGRectMake(0, 0, 100, 100); // 大小
    layer.
position = CGPointMake(150, 150); // 位置
    layer.
backgroundColor = [UIColor redColor].CGColor; // 颜色
   
//    layer.opacity = 0.5; // 透明度

   
// 把创建的layer添加到控制器viewlayer
    [
self.view.layer addSublayer:layer];
   
//赋值回去启动全局
   
self.layer = layer;
}
- (
void)touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event
{

    // 如何禁用隐式动画
    [
CATransaction begin]; // 开启事务;
    [
CATransaction setDisableActions:YES]; // 禁用隐式动画

   
// 获取触摸对象
   
UITouch* t = touches.anyObject;
   
// 获取手指的位置
   
CGPoint p = [t locationInView:t.view];
   
// layer的位置 跑到手指的位置上来
   
self.layer.position = p;

    [
CATransaction commit]; // 提交事务


控制器的根layer没有隐是动画,layer可以创建很多个,每一个小的layer都会有隐式动画
证明::
创建的一个小的layer
    CALayer *layer =[[ CALayer alloc ] init ];
   
    layer.
position = CGPointMake ( 100 , 100 );
   
    layer.
bounds = CGRectMake ( 0 , 0 , 200 , 200 );
   
    layer.
backgroundColor = [ UIColor redColor ]. CGColor ;
   
    [
self . view . layer addSublayer :layer];
   
   
self . layer = layer;
   
   


   
//    [self test1];
}

- (
void )touchesBegan:( NSSet *)touches withEvent:( UIEvent *)event
{
   
// 获取触摸对象
   
UITouch * t = touches. anyObject ;
   
// 获取位置
   
CGPoint p = [t locationInView :t. view ];
   
// layer 的位置等于手指的位置
    self.layer.position = p;

view的根layer是没有隐式动画的
  self . view . backgroundColor = [ UIColor lightGrayColor ];
  
//View 的大小
   
UIView * view1 = [[ UIView alloc ] initWithFrame : CGRectMake ( 100 , 100 , 100 , 100 )];
   
//View 的背景颜色
    view1.
backgroundColor = [ UIColor redColor ];
   
// 赋值回去
   
self . layer = view1. layer ;

   
// 1> 边框
    view1.
layer . borderWidth = 10 ;
    view1.
layer . borderColor = [ UIColor whiteColor ]. CGColor ;

   
// 2> 阴影
    view1.
layer . shadowColor = [ UIColor blueColor ]. CGColor ;
   
//    view1.layer.shadowOffset = CGSizeMake(50, 50);
    view1.
layer . shadowOpacity = 1 ;
    view1.
layer . shadowRadius = 50 ;

   
// 3> 圆角
    view1.
layer . cornerRadius = 50 ;
    view1.
layer . masksToBounds = YES ;

   
// 4>bounds
    view1.
layer . bounds = CGRectMake ( 0 , 0 , 200 , 200 );

   
// 5>postion 属性和 view.center 的关系 ( 默认情况下 )
    view1.
layer . position = CGPointMake ( 100 , 100 );

   
// 6> 设置内容 ( 图片 )
    view1.layer.contents = (__bridge id)([UIImage imageNamed:@"me"].CGImage);

[self.view addSubView
:view];
实现效果:


2.layer的transform属性
1.首先创建一个layer对象

   
// 创建layer对象
   
CALayer* layer = [[CALayer alloc] init];
   
self.layer = layer;

    layer.
bounds = CGRectMake(0, 0, 100, 100); // 大小
    layer.
position = CGPointMake(150, 150); // 位置
    layer.
backgroundColor = [UIColor redColor].CGColor; // 颜色
   
//    layer.opacity = 0.5; // 透明度
    layer.
contents = (__bridge id)([UIImage imageNamed:@"me"].CGImage);
   
// 把创建的layer添加到控制器viewlayer
    [self.view.layer addSublayer:layer];

1.旋转CATransform3DRotate
- ( void )touchesBegan:( NSSet *)touches withEvent:( UIEvent *)event
{

   
// 旋转
    //    self.layer.transform = CATransform3DRotate(self.layer.transform, M_PI_4, 0, 0, 1);

2.缩放CATransform3DScale
// 缩放 (z 无效 )
    //    self.layer.transform = CATransform3DScale(self.layer.transform, 1, 1, 0.5);

3.平移CATransform3DTranslate
  // 平移 (z 无效 )
    self.layer.transform = CATransform3DTranslate(self.layer.transform, 0, 0, 100);

五.时钟练习
代码如下:
#import "ViewController.h"

@interface ViewController ()

@property (weak, nonatomic) CALayer* second;

@end

@implementation ViewController

- (
void)viewDidLoad
{
    [
super viewDidLoad];
   
// Do any additional setup after loading the view, typically from a nib.

   
// 控制器的背景颜色
   
self.view.backgroundColor = [UIColor orangeColor];

   
// 创建一个clocklayer
   
CALayer* clock = [[CALayer alloc] init];
   
// 位置
    clock.
position = CGPointMake(200, 200);
   
// 大小
    clock.
bounds = CGRectMake(0, 0, 200, 200);
   
// 内容
    clock.
contents = (__bridge id)([UIImage imageNamed:@"clock"].CGImage);
   
// 圆角
    clock.
cornerRadius = 100;
    clock.
masksToBounds = YES;

   
// 创建一个指针
   
CALayer* second = [[CALayer alloc] init];
   
// 位置
    second.
position = clock.position;
   
// 大小
    second.
bounds = CGRectMake(0, 0, 2, 100);
   
// 颜色
    second.
backgroundColor = [UIColor redColor].CGColor;
   
// 定位点 锚点
    second.
anchorPoint = CGPointMake(0.5, 0.8);

   
// 把表和针添加到控制器viewlayer
    [
self.view.layer addSublayer:clock];
    [
self.view.layer addSublayer:second];
   
//赋值回去,锁定全局
   
self.second = second;
   
//让时钟为0开始
    [
self timeChange];

   
//一个做为layer的计时器
   
CADisplayLink* link = [CADisplayLink displayLinkWithTarget:self selector:@selector(timeChange)];
    [link
addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
}

- (
void)timeChange
{
   
//一圈
   
CGFloat angle = 2 * M_PI / 60;

   
// 2.NSCalendar
   
NSDate* date = [NSDate date];
   
NSCalendar* cal = [NSCalendar currentCalendar];
   
//
   
CGFloat secondFloat = [cal component:NSCalendarUnitSecond fromDate:date];
   
// 毫秒
   
CGFloat secondFloat1 = [cal component:NSCalendarUnitNanosecond fromDate:date];

   
// 以毫秒去旋转
    secondFloat = secondFloat + secondFloat1 *
0.000000001;
   
//想用layercgaff的属性就得用affineTransform
   
self.second.affineTransform = CGAffineTransformMakeRotation(secondFloat * angle);
}
实现效果:

六核心动画
1.基本动画 CABasicAnimation
创建一个layer
super viewDidLoad];
   
// 创建layer
   
CALayer* layer = [[CALayer alloc] init];
    layer.
backgroundColor = [UIColor redColor].CGColor; // 颜色
    layer.
position = CGPointMake(200, 200); // 位置
    layer.
bounds = CGRectMake(0, 0, 100, 100); // 大小

   
// 添加到控制器viewlayer
    [self.view.layer addSublayer:layer];


//当屏幕点击的时候
- ( void )touchesBegan:( NSSet *)touches withEvent:( UIEvent *)event
{

   
// 基本动画
   
// 1. 创建核心动画的对象
   
CABasicAnimation * anim = [[ CABasicAnimation alloc ] init ];
   
   
// 2. 设置核心动画的操作
    anim.
keyPath = @"transform.rotation" ;

   
//    anim.fromValue = @(100); // 从哪
   
//    anim.toValue = @(300); // 到哪

    anim.
byValue = @( M_PI_4 ) ; //

   
// 动画完毕以后不回到原来的位置
    anim.
fillMode = kCAFillModeForwards ;
    anim.
removedOnCompletion = NO ;

   
// 3. 添加到 layer
    [
self . layer addAnimation :anim forKey : nil ];
}

//关键帧动画CAKeyframeAnimation
代码如下:

   
// 关键帧动画
   
// 1.创建对象
   
CAKeyframeAnimation* anim = [[CAKeyframeAnimation alloc] init];

   
// 2.操作
    anim.
keyPath = @"position";

   
NSValue* v1 = [NSValue valueWithCGPoint:CGPointMake(50, 50)];
   
NSValue* v2 = [NSValue valueWithCGPoint:CGPointMake(150, 50)];
   
NSValue* v3 = [NSValue valueWithCGPoint:CGPointMake(50, 150)];
   
NSValue* v4 = [NSValue valueWithCGPoint:CGPointMake(150, 150)];

    anim.
values = @[ v1, v2, v3, v4 ];

    anim.
duration = 5; // 设置时间

   
// 补间动画

   
// 动画完毕以后不回到原来的位置
    anim.
fillMode = kCAFillModeForwards;
    anim.
removedOnCompletion = NO;

   
// 3.添加
    [self.layer addAnimation:anim forKey:nil];

2.第二种,根据图形
{
   
// 关键帧动画
   
// 1.创建对象
   
CAKeyframeAnimation* anim = [[CAKeyframeAnimation alloc] init];

   
// 2.操作
    anim.
keyPath = @"position";

   
// 用画弧的方式 画圆
   
//    UIBezierPath* path = [UIBezierPath bezierPathWithArcCenter:CGPointMake(150, 150) radius:50 startAngle:0 endAngle:2 * M_PI clockwise:1];
   
// 用椭圆的方式 画圆
   
UIBezierPath* path = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(100, 100, 100, 100)];

    anim.
path = path.CGPath;

    anim.
duration = 3;
    anim.
repeatCount = INT_MAX; // 重复次数

   
// 补间动画

   
// 动画完毕以后不回到原来的位置
    anim.
fillMode = kCAFillModeForwards;
    anim.
removedOnCompletion = NO;

   
// 3.添加
    [
self.layer addAnimation:anim forKey:nil];
}
第三种.关键帧动画,是由每个的帧来运动的,使用椭圆都会停顿,因为它的四个帧是矩形
代码如下:
// -----------------------------------------
   
// 关键帧动画
   
// 1.创建对象
   
CAKeyframeAnimation* anim = [[CAKeyframeAnimation alloc] init];

   
// 2.操作
    anim.
keyPath = @"position";

   
// 用画弧的方式 画圆
   
//    UIBezierPath* path = [UIBezierPath bezierPathWithArcCenter:CGPointMake(150, 150) radius:50 startAngle:0 endAngle:2 * M_PI clockwise:1];
   
// 用椭圆的方式 画圆
   
UIBezierPath* path = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(100, 100, 100, 100)];

    anim.
path = path.CGPath;

    anim.
duration = 3;
    anim.
repeatCount = INT_MAX; // 重复次数

   
// 补间动画

   
// 动画完毕以后不回到原来的位置
    anim.
fillMode = kCAFillModeForwards;
    anim.
removedOnCompletion = NO;

   
// 3.添加
    [
self.layer addAnimation:anim forKey:nil];
   
// -----------------------------------------

   
// -----------------------------------------
   
// 关键帧动画
   
// 1.创建对象
   
CAKeyframeAnimation* anim1 = [[CAKeyframeAnimation alloc] init];

   
// 2.操作
    anim1.
keyPath = @"position";

   
// 用画弧的方式 画圆
   
//    UIBezierPath* path = [UIBezierPath bezierPathWithArcCenter:CGPointMake(150, 150) radius:50 startAngle:0 endAngle:2 * M_PI clockwise:1];
   
// 用椭圆的方式 画圆
   
UIBezierPath* path1 = [UIBezierPath bezierPathWithRect:CGRectMake(100, 100, 100, 100)];

    anim1.
path = path1.CGPath;

    anim1.
duration = 3;
    anim1.
repeatCount = INT_MAX; // 重复次数

   
// 补间动画

   
// 动画完毕以后不回到原来的位置
    anim1.
fillMode = kCAFillModeForwards;
    anim1.
removedOnCompletion = NO;

   
// 3.添加
    [
self.layer1 addAnimation:anim1 forKey:nil];

    // -----------------------------------------

五,组动画,是由两个动画合并的
组动画:CAAnimationGroup
代码如下 :

   
// 1. 创建对象
   
CAAnimationGroup * group = [[ CAAnimationGroup alloc ] init ];

   
// 2. 操作

   
// ----- 1.
   
// 基本动画
   
// 1. 创建核心动画的对象
   
CABasicAnimation * anim = [[ CABasicAnimation alloc ] init ];

   
// 2. 设置核心动画的操作
    anim.
keyPath = @"transform.rotation" ;

   
//    anim.fromValue = @(100); // 从哪
   
//    anim.toValue = @(300); // 到哪

    anim.
byValue = @( M_PI * 2 * 50) ;
   
// ----- 2.
   
// 关键帧动画
   
// 1. 创建对象
   
CAKeyframeAnimation * anim1 = [[ CAKeyframeAnimation alloc ] init ];

   
// 2. 操作
    anim1.
keyPath = @"position" ;

   
// 用画弧的方式 画圆
   
UIBezierPath * path = [ UIBezierPath bezierPathWithArcCenter : CGPointMake ( 150 , 150 ) radius : 50 startAngle : 0 endAngle : 2 * M_PI clockwise : 1 ];

    anim1.
path = path. CGPath ;

    group.
animations = @[ anim1, anim ] ; // 添加到组动画去

    group.
repeatCount = INT_MAX ; // 重复次数
    group.
duration = 3 ;

   
// 3. 添加
    [self.layer addAnimation:group forKey:nil];
实现效果:

六:转场动画

代码如下

- (
IBAction)swipe:(UISwipeGestureRecognizer*)sender
{
   
self.imageName++;

   
if (self.imageName == 5) {
       
self.imageName = 0;
    }

   
UIImage* image = [UIImage imageNamed:[NSString stringWithFormat:@"%d", self.imageName + 1]];

   
CATransition* anim = [[CATransition alloc] init];
    anim.
type = @"cameraIrisHollowOpen";

   
// 判断左右
   
if (sender.direction == UISwipeGestureRecognizerDirectionLeft) {
       
//
       
self.imageView.image = image;
        anim.
subtype = kCATransitionFromRight;
    }
   
else {
       
//
       
self.imageView.image = image;
        anim.
subtype = kCATransitionFromLeft;
    }

    [
self.imageView.layer addAnimation:anim forKey:nil];
}
样式:

九:小画板案例
1.布局界面
2.画线

- (
UIBezierPath*)path
{
   
if (!_path) {
       
_path = [UIBezierPath bezierPath];
    }
   
return _path;
}

- (
void)touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event
{
   
// 获取触摸对象
   
UITouch* t = touches.anyObject;

   
// 获取手指的位置
   
CGPoint p = [t locationInView:t.view];

   
// 移动到到手指点击时候的位置
    [
self.path moveToPoint:p];
}

- (
void)touchesMoved:(NSSet*)touches withEvent:(UIEvent*)event
{
   
// 获取触摸对象
   
UITouch* t = touches.anyObject;

   
// 获取手指的位置
   
CGPoint p = [t locationInView:t.view];

   
// 画线到手指移动时候的位置
    [
self.path addLineToPoint:p];

   
// 重绘
    [
self setNeedsDisplay];
}

// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (
void)drawRect:(CGRect)rect
{
    [
self.path stroke];
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值