iOS开发-绘制

IOS开发-CALayer和UIView的理解

2018-06-07  本文已影响9人  小飞飞啊阿飞

1.    CALayer和UIView之间的关系:

 在iOS系统中,你能看得见摸得着的东西基本上都是UIView,比如UI控件、图标等等,都是UIView。

 其实UIView之所以能显示在屏幕上,完全是因为它内部的一个层(CALayer)。

 在创建UIView对象时,UIView内部会自动创建一个层(即CALayer对象),通过UIView的layer属性可以访问这个层。当UIView需要显示到屏幕上时,会调用drawRect:方法进行绘图,并且会将所有内容绘制在自己的层上,绘图完毕后,系统会将层拷贝到屏幕上,于是就完成了UIView的显示。

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

UIView之所以能够显示,完全是因为内部的CALayer对象。因此,通过操作这个CALayer对象,可以很方便地调整UIView的一些界面属性,比如:阴影、圆角大小、边框宽度和颜色等。

UIView相对于CALayer来说就是多一个事件处理的功能,CALayer是不能处理用户的触摸事件。故如果显示出来的东西需要跟用户进行交互的话,用UIView;如果不需要跟用户进行交互,用UIView或者CALayer都可以。

2.为什么CALayer中使用CGColorRef和CGImageRef这2种数据类型,而不用UIColor和UIImage?

* 首先要知道:CALayer是定义在QuartzCore框架中的;CGImageRef、CGColorRef两种数据类型是定义在CoreGraphics框架中的;UIColor、UIImage是定义在UIKit框架中的

* 其次,QuartzCore框架和CoreGraphics框架是可以跨平台使用的,在iOS和Mac OS X上都能使用,但是UIKit只能在iOS中使用

* 因此,为了保证可移植性,QuartzCore不能使用UIImage、UIColor,只能使用CGImageRef、CGColorRef

* 不过很多情况下,可以通过UIKit对象的特定方法,得到CoreGraphics对象,比如UIImage的CGImage方法可以返回一个CGImageRef

3.UIView的显示过程

 1.   当UIView需要显示时,它内部的层会准备好一个CGContextRef(图形上下文),然后调用delegate(这里就是UIView)的drawLayer:inContext:方法,并且传入已经准备好的CGContextRef对象。而UIView在drawLayer:inContext:方法中又会调用自己的drawRect:方法

   2.  在drawRect:中通过UIGraphicsGetCurrentContext()获取的就是由层传入的CGContextRef对象,在drawRect:中完成的所有绘图都会填入层的CGContextRef中,然后被拷贝至屏幕

(1).新建一个继承于CALayer的类AACALayer,然后覆盖drawInContext:方法,在里面绘图

-(void)drawInContext:(CGContextRef)abc{

     CGContextSetRGBFillColor(abc,0, 1, 0.5, 1);//填充,出现实心

  //    起点

     CGContextMoveToPoint(abc,50, 0);

  // 从(50, 0)连线到(0, 100)

     CGContextAddLines(abc,0, 100);

 // 从(0, 100)连线到(100, 100)

    CGContextAddLineToPoint(abc,100, 100);

 //    绘制路径

     CGContextClosePath(abc);

   }

(2).不想写子类,也可以直接使用代理可以新建层,drawLayer:(CALayer *)layer inContext:(CGContextRef)ctx中绘图,但是不能将UIView设置为它的代理,否则和UIView内部就冲突了,因为UIView已经是内部根图层的degegate了。

-(void)viewDidLoad{

    CALayer *layerr = [CALayer layer];

     // 设置层的宽高

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

   // 设置层的位置

   layerr.position = CGPointMake(100, 100);

   laere.delegate - self;

   // 开始绘制图层

   [layer setNeedsDisplay];//无论采取哪种方法来自定义层,都必须调用CALayer的setNeedsDisplay方法才能正常绘图。

    [self.view.layer addSublayer:layer];

   }

//在代理方法中

 - (void)drawLayer:(CALayer *)layer inContext:(CGContextRef)ctx {

      CGContextSetRGBStrokeColor(ctx,0, 0, 1, 1);//这不填充,空心

     CGContextSetLineWidth(ctx,5);

     CGContextAddRect(ctx, layer.bounds);

     CGContextStrokePath(ctx);

}

上一篇下一篇

猜你喜欢

热点阅读