CALayer
CALayer(这里简单地称其为层,与photoshop里的层类似)。
首先要说的是CALayers 是屏幕上的一个具有可见内容的矩形区域,每个UIView都有一个根CALayer,其所有的绘制(视觉效果)都是在这个layer上进行的。
CALayer可以影响UIView的外观的特性有:
层的大小尺寸背景色内容(比如图像或是使用Core Graphics绘制的内容)是否使用圆角是否使用阴影等等。
需要说明的是CALayer的大部分属性都可以用来实现动画效果。
另外,你可以直接使用CALayer,也可以使用其子类,如CAGradientLayer,CATextLayer, CAShapeLayer等等。
示例:
-
首先在项目中导入 QuartzCore.framework 框架
1 #import "ViewController.h" 2 #import <QuartzCore/QuartzCore.h> 3 @interface ViewController () 4 @property (nonatomic,retain) UIImageView *img; 5 @end 6 7 @implementation ViewController 8 9 - (void)viewDidLoad 10 { 11 [super viewDidLoad]; 12 [self initImage]; 13 14 } 15 16 #pragma mark - Private Method 17 -(void)initImage{ 18 _img = [[UIImageView alloc] initWithFrame:CGRectMake(100, 150, 100, 150)]; 19 self.img.image = [UIImage imageNamed:@"0005.jpg"]; 20 [self.view addSubview:self.img]; 21 }
-
添加边框和圆角
1 -(void)corner{ 2 //设置圆角弧度 3 self.img.layer.cornerRadius = 10; 4 //剪切圆角之外的部分,在没有加边框的情况下,不设置该属性,看不出圆角 5 self.img.layer.masksToBounds = YES; 6 //设置边框颜色 7 self.img.layer.borderColor = [UIColor blackColor].CGColor; 8 //设置边框宽度 9 self.img.layer.borderWidth = 3; 10 }
-
添加阴影
1 -(void)shadow{ 2 //设置阴影的颜色 3 self.img.layer.shadowColor = [UIColor blueColor].CGColor; 4 //设置阴影的偏移量 5 self.img.layer.shadowOffset = CGSizeMake(10, 10); 6 //设置阴影的透明度,默认为0 7 self.img.layer.shadowOpacity = 0.8; 8 //设置阴影的圆角 9 self.img.layer.shadowRadius = 5; 10 //设置阴影的frame 11 self.img.layer.shadowPath = [UIBezierPath bezierPathWithRect:CGRectMake(50, -40, 100, 100)].CGPath; 12 }
为什么要将添加圆角和阴影分开写呢??如果你同时调用这两个方法,你会发现,阴影没了,只有边框和圆角了。这是因为在设置layer的masksToBounds = YES属性的时候,其裁剪掉了圆角以外的视图,包括layer的子layer上的视图(若layer上没有图片等视图,只有背景色等,不会对其阴影进行裁剪,也就是说layer只有背景色的时候,可以同时设置圆角和阴影)。
所以想要阴影,又想要圆角,那么我们可以再添加一个layer放在img.layer的下面,用这个layer来设置阴影,img.layer设置圆角。
1 -(void)cornerAndShadow{ 2 // img 3 //设置圆角弧度 4 self.img.layer.cornerRadius = 10; 5 //剪切圆角之外的部分,在没有加边框的情况下,不设置该属性,看不出圆角 6 self.img.layer.masksToBounds = YES; 7 //设置边框颜色 8 self.img.layer.borderColor = [UIColor blackColor].CGColor; 9 //设置边框宽度 10 self.img.layer.borderWidth = 3; 11 12 //阴影层 13 CALayer *layer = [CALayer layer]; 14 layer.frame = self.img.frame; 15 layer.backgroundColor = [UIColor redColor].CGColor; 16 layer.shadowColor = [UIColor blueColor].CGColor; 17 layer.shadowOffset = CGSizeMake(10, 10); 18 layer.shadowOpacity = 0.5; 19 //设置该层的圆角 20 layer.cornerRadius = 10; 21 //将该层添加在img层的下面 22 [self.view.layer insertSublayer:layer below:self.img.layer]; 23 }
UIView与CALayer的区别?
- UIView是iOS系统中界面元素的基础,所有的界面元素都继承自它。它本身完全是由CoreAnimation来实现的(Mac下似乎不是这样)。它真正的绘图部分,是由一个叫CALayer(Core Animation Layer)的类来管理。UIView本身,更像是一个CALayer的管理器,访问它的跟绘图和跟坐标有关的属性,例如frame,bounds等等,实际上内部都是在访问它所包含的CALayer的相关属性。
- UIView有个layer属性,可以返回它的主CALayer实例,UIView有一个layerClass方法,返回主layer所使用的类,UIView的子类,可以通过重载这个方法,来让UIView使用不同的CALayer来显示,例如通过下面方法,使某个UIView的子类使用GL来进行绘制。
1 - (class) layerClass { 2 return ([CAEAGLLayer class]); 3 }
- UIView的CALayer类似UIView的子View树形结构,也可以向它的layer上添加子layer,来完成某些特殊的表示。上面例子已经用到过了。
- UIView的layer树形在系统内部,被系统维护着三份copy(这段理解有点吃不准)。
第一份,逻辑树,就是代码里可以操纵的,例如更改layer的属性等等就在这一份。
第二份,动画树,这是一个中间层,系统正在这一层上更改属性,进行各种渲染操作。
第三份,显示树,这棵树的内容是当前正被显示在屏幕上的内容。
这三棵树的逻辑结构都是一样的,区别只有各自的属性。 - 动画的运作
UIView的主layer以外(我觉得是这样),对它的subLayer,也就是子layer的属性进行更改,系统将自动进行动画生成,动画持续时间有个缺省时间,个人感觉大概是0.5秒。在动画时间里,系统自动判定哪些属性更改了,自动对更改的属性进行动画插值,生成中间帧然后连续显示产生动画效果。 - 坐标系系统(对position和anchorPoint的关系还是犯晕)
CALayer的坐标系系统和UIView有点不一样,它多了一个叫anchorPoint的属性,它使用CGPoint结构,但是值域是0~1,也就是按照比例来设置。这个点是各种图形变换的坐标原点,同时会更改layer的position的位置,它的缺省值是{0.5, 0.5},也就是在layer的中央。
某layer.anchorPoint = CGPointMake(0.f, 0.f);
如果这么设置,layer的左上角就会被挪到原来的中间的位置,
加上这样一句就好了
某layer.position = CGPointMake(0.f, 0.f);
-
通过layer做一些动画
1 -(void)scale{ 2 //创建动画 3 CABasicAnimation* theAnimation = [CABasicAnimation animationWithKeyPath:@"transform"]; 4 //结束状体比例,CATransform3D的类型 x,y,z 缩放比 5 CATransform3D transform = CATransform3DMakeScale(2.5, 2.5, 1.0); 6 //设置结束状态 7 [theAnimation setToValue:[NSValue valueWithCATransform3D:transform]]; 8 //初始状态比例 9 transform = CATransform3DMakeScale(1.0, 1.0, 1.0); 10 //设置初始状态 11 [theAnimation setFromValue:[NSValue valueWithCATransform3D:transform]]; 12 //原路返回 13 [theAnimation setAutoreverses:YES]; 14 //动画的时间 15 [theAnimation setDuration:2.0]; 16 //动画重复的次数 17 [theAnimation setRepeatCount:3]; 18 //将动画加在img的layer上 19 [self.img.layer addAnimation:theAnimation forKey:nil]; 20 }
上面代码实现了img的按比例缩放。平移,旋转同理
1 //1.57 所旋转角度的弧度值 90° =》 90*3.14/180 0 代表不旋转此轴 1 代表旋转此轴 2 CATransform3D transform = CATransform3DMakeRotation(25*M_PI/180, 0, 0, 1); 3 //平移 4 CATransform3D transform1 = CATransform3DMakeTranslation(50, 10, 1);