CALayer的使用(圆形头像 锚点 边框 阴影 形变 隐式动画 )

来源:互联网 发布:php源码站 编辑:程序博客网 时间:2024/05/28 23:12

 CALayer简介和一些基本概念:

 

 iOS中,你能看得见摸得着的东西基本上都是UIView,比如一个按钮、一个文本标签、一个文本输入框、一个图标等等,这些都是UIView.其实UIView之所以能显示在屏幕上,完全是因为它内部的一个图层.在创建UIView对象时,UIView内部会自动创建一个图层(CALayer对象),通过UIViewlayer属性可以访问这个层.

 

 Core Animation是跨平台的,支持iOS环境和Mac OS X环境,在核心动画中,需要先理解CALayer,核心动画操作的对象不是UIView,而是CALayer.在使用Core Animation开发动画的本质就是将CALayer中的内容转化为位图从而供硬件操作.通过操作CALayer对象,可以很方便地调整UIView的一些外观属性.比如,可以做圆角、阴影、边框等效果.


 图层和视图之间的关系:

 

   1:创建视图对象时,视图会自己创建一个层,视图在绘图(如drawRect:)时,会将内容画在自己的层上。当视图在层上完成绘图后,系统会将图层拷贝至屏幕(换句话说,UIView本身不具备显示的功能,是它内部的层才有显示功能.)。每个视图都有一个层,而每个图层又可以有多个子层.


   提示:

    CALayer的设计目的不是为了取代视图,因此不能基于CALayer创建一个独立的可视化组件

    CALayer的设计目的是提供视图的基本可视内容,从而提高动画的执行效率

   除提供可视内容外,Layer不负责视图的事件响应、内容绘制等工作,同时Layer不能参与到响应者链条中.其实,对比CALayerUIView多了一个事件处理的功能。也就是说,CALayer不能处理用户的触摸事件,而UIView可以。所以,如果显示出来的东西需要跟用户进行交互的话,用UIView;如果不需要跟用户进行交互,用UIView或者CALayer都可以。当然,CALayer的性能会高一些,因为它少了事件处理的功能,更加轻量级.



 CALayer的使用说明:

 

   通过UIViewlayer属性可以拿到对应的根层,这个层不允许重新创建,但可以往层里面添加子层(调用CALayeraddSublayer)要具体使用CALayer,需要引入<QuartzCore/QuartzCore.h>

 

   获取当前图层或使用静态方法layer初始化CALayer后,可以设置以下属性:

 

    bounds: 宽度和高度

    position位置(默认指中心点,具体由anchorPoint决定)

    anchorPoint锚点(x,y的范围都是0-1),决定了position的含义.默认值为(0.5,0.5

    backgroundColor: 背景颜色(CGColorRef类型)

    borderColor边框颜色(CGColorRef类型)

    borderWidth边框宽度

    cornerRadius圆角半径

    contents: 内容(比如设置为图片CGImageRef

    transform旋转、缩放、平移

    contentsRect图层显示内容的大小和位置

    doubleSided图层背面是否显示,默认为YES


   注意:

      1:虽然CALayer可以使用frame,但最好还是使用boundsposition。为层设置动画时,用boundsposition会方便一点.而且frame本身不支持动画效果,通常使用boundsposition代替.

      2:隐式属性动画的本质是这些属性的变动默认隐含了CABasicAnimation动画实现.

      3:CALayer中透明度使用opacity表示而不是alpha;中心点使用position表示而不是center

      4:anchorPoint属性是图层的锚点,范围在(0~1,0~1)表示在xy轴的比例,这个点永远可以同position(中心点)重合,当图层中心点固定后,调整anchorPoint即可达到调整图层显示位置的作用(因为它永远和position重合).


#import "MainViewController.h"

#import <QuartzCore/QuartzCore.h>


@implementation MainViewController

#define WIDTH 50


- (void)viewDidLoad

{

      [super viewDidLoad];

      [self myImageLayerDemo];//头像效果

    //[self drawMyLayer];

    //[self testAnchorPoint];

}


#pragma mark - UIImageViewlayer演练

- (void)myImageLayerDemo

{

    UIImage *image = [UIImage imageNamed:@"头像1.png"];

    UIImageView *imageView = [[UIImageView alloc]initWithImage:image];

    [imageView setFrame:CGRectMake(100,100,200,200)];

    [self.view addSubview:imageView];

    

    // 1. 圆角半径

    //提示,在imageView中,图层不止一个,如果要实现圆角效果,需要设置一个遮罩属性

    // masksToBounds属性可以让imageView中的所有子图层跟随imageView一起变化

    imageView.layer.cornerRadius =50.0f;

    [imageView.layer setMasksToBounds:YES];


    // 2. 阴影

    //提示,如果设置了masksToBounds属性,imageView的阴影效果无效.如果要实现阴影效果.解决办法:可以在底层附加一个UIView实现阴影效果.也可以通过Quartz 2D进行分别绘制.

    [imageView.layer setShadowColor:[UIColor redColor].CGColor];//注意:UIKit框架只能应用在iOS而不能用于Mac,但是Quartz 2D是可以跨平台的,因此在使用颜色时,不能直接使用UIColor而需要将颜色转成CGColor.

    

    [imageView.layer setShadowOffset:CGSizeMake(10.0,10.0)];

    [imageView.layer setShadowOpacity:1.0];

    

    // 3. 边框

    [imageView.layer setBorderColor:[UIColor blueColor].CGColor];

    [imageView.layer setBorderWidth:3.0f];

    

    // 4. 形变属性,在CALayer中的形变属性是3D的,不再是2D

    //提示,形变参数使用set方法时,只能应用一种形变

    // 1> 平移属性(向上移动100个点)

    //[imageView.layer setTransform:CATransform3DMakeTranslation(0, -100, 0)];

    // 2> 缩放属性

    //[imageView.layer setTransform:CATransform3DMakeScale(0.5, 1.0, 1.0)];

    // 3> 旋转属性

    //提示:通常在旋转时指定z轴即可,要延哪个轴旋转,指定一个数值1.0即可

    //图像本身没有厚度,如果按照xy旋转90度,图像是不可见的。

    //[imageView.layer setTransform:CATransform3DMakeRotation(M_PI_2, 0, 0, 1.0)];


    // 5.利用keyPath设置形变,可以组合使用,但是记住不要写错了.

    // 提示,在文档中输入transform3D可以找到对应的transform keyPath.可以传递哪些key path,在官方文档搜索 "CATransform3D key paths"

    

    // 1)平移 -100及向上移动100个点.

    [imageView.layer setValue:@-100 forKeyPath:@"transform.translation.y"];

    // 2) 缩放 0.5及为原来大小的一半

    [imageView.layer setValue:@0.5 forKeyPath:@"transform.scale"];

    // 3) 旋转

    [imageView.layer setValue:@M_PI_2 forKeyPath:@"transform.rotation.z"];

}


效果图如下:


         



#pragma mark 隐形动画的小例子 (每一个UIView内部都默认关联着一个CALayer,我们可用称这个LayerRoot Layer(根层)。所有的非Root Layer,也就是手动创建的CALayer对象,都存在着隐式动画.) 程序初始化阶段我们定义一个正方形,但是圆角路径调整为正方形边长的一般,使其看起来是一个圆形,在点击屏幕的时候修改图层的属性形成动画效果(注意在程序中没有直接修改UIViewlayer属性,因为根图层无法形成动画效果)


-(void)drawMyLayer{

    

    CGSize size=[UIScreen mainScreen].bounds.size;

    

    //获得根图层

    CALayer *layer=[[CALayer alloc]init];

    //设置背景颜色

    layer.backgroundColor=[UIColor colorWithRed:0 green:146/255.0 blue:1.0 alpha:1.0].CGColor;

    //设置中心点

    layer.position=CGPointMake(size.width/2, size.height/2);

    //设置大小

    layer.bounds=CGRectMake(0,0,WIDTH,WIDTH);

    //设置圆角,当圆角半径等于矩形的一半时看起来就是一个圆形

    layer.cornerRadius=WIDTH/2;

    //设置阴影

    layer.shadowColor=[UIColor grayColor].CGColor;

    layer.shadowOffset=CGSizeMake(2,2);

    layer.shadowOpacity=.9;

    

    [self.view.layer addSublayer:layer]; 

}


//点击放大,缩小

-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{

    

    UITouch *touch=[touches anyObject];

    CALayer *layer=self.view.layer.sublayers[0];

    CGFloat width=layer.bounds.size.width;

   if (width==WIDTH) {

        width=WIDTH*4;

    }else{

        width=WIDTH;

    }

    layer.bounds=CGRectMake(0,0, width, width);

    layer.position=[touch locationInView:self.view];

    layer.cornerRadius=width/2;

}


 

               

         最开始运行得到的界面效果                 

         




       

      点击界面之后,视图会以动画方式迅速移动到点击的位置并且变大


#pragma mark 瞄点的使用 如图所示:

anchorPoint

它的取值为0~1

 

红色图层的anchorPoint为(0,0)

红色图层的anchorPoint为(0.5,0.5)

红色图层的anchorPoint为(1,1)

红色图层的anchorPoint为(0.5,0)

position和anchorPoint

添加一个红色图层到绿色图层上,红色图层显示到什么位置,由position属性决定

假设红色图层的position是(100,100)

  到底把红色图层的哪个点移动到(100,100)的坐标位置,锚点。

  红色图层的锚点是(0,0)

红色图层的锚点是(0.5,0.5)

红色图层的锚点是(1,1)

红色图层的锚点是(0.5,0)

     


-(void)testAnchorPoint{

    

    CALayer *myLayer=[CALayer layer];

   //设置了myLayerposition(100, 100),又因为anchorPoint默认是(0.5, 0.5),所以最后的效果是:myLayer的中点会在父层的(100, 100)位置

    myLayer.bounds=CGRectMake(0,0,100,100);

    // 设置层的位置

    myLayer.position=CGPointMake(100,100);

    myLayer.backgroundColor=[UIColor redColor].CGColor; 


    //情形1默认瞄点为(0.5, 0.5)

    

    //情形2默认瞄点为(0, 0).

    //myLayer.anchorPoint=CGPointMake(0,0);

    

    //情形3默认瞄点为(1, 0).

   //myLayer.anchorPoint=CGPointMake(1,0);

    

   //情形4默认瞄点为(1, 1).

   //myLayer.anchorPoint=CGPointMake(1,1);

   

    // 添加myLayer到控制器的viewlayer

    [self.view.layer addSublayer:myLayer];


}

@end


 
        
                    情形1默认瞄点为(0.5, 0.5)
  
          
 
    
                     情形2默认瞄点为(0, 0).

  
        情形3默认瞄点为(1, 0).

 
         情形4默认瞄点为(1, 1)


0 0