CALayer使用

iOS的设备中,我们之所以能看到各种各样的控件、文字、图片,都是Core Animation框架的功劳。它通过图层的合成,最终显示在屏幕上。而今天这篇文章讲的就是Core Animation使用的图层— CALayer。每一个UIView都有一个对应的一个CALayer,这个CALayer可能是一个图层,也可能是多个图层的叠加。事实上,在很多复杂的页面中,我们应该使用图层的叠加来显示,这样做的好处是保证显示的逻辑结构清晰。这篇文章主要介绍CALayer的一些属性以及它的使用,同时写一份Demo演示如何自定义的创建一个自定义的CALayer。

一、CALayer的属性

和UIView类似,CALayer也包括frame、backgroundColor等属性。 这些属性在被设置的时候直接对UIView有效。同时CALayer还有一些UIView没有的属性,比如圆角、阴影等等。先看下面CALayer的一个属性表:

 
属性名 描述
CGRect bounds; 描述了CALayer的位置信息
CGPoint position; 描述CALayer的坐标   
CGFloat zPosition; 描述CALAayer的层级  比如想将某个图层放在最上面,可以将它的层级设置到更高
CGPoint anchorPoint; 描点,默认情况的描点是 (0.5,0.5),也即是中心的位置。 
CGFloat anchorPointZ; 不明白
CATransform3D transform; 3D的形变  包括缩放、旋转
BOOL hidden; 是否隐藏
BOOL geometryFlipped; 直到OS X 10.8才出现了geometryFlipped属性,该属性可以改变默认图层y坐标的方向。当翻转变换被调用时,使用该属性来调整图层的方向有的时候是必需的。如果父视图使用了翻转变换,它的子视图内容(以及它对应的图层)将经常被颠倒。在这种情况下,设置子图层的geometryFlipped属性为YES是一种修正该问题最简单的方法。在OS X 10.8及以上版本,AppKit负责管理该属性,你不应该更改它。对于iOS app,不推荐使用geometryFlipped属性。表示坐标系是否翻转
CALayer *mask; 蒙版
BOOL masksToBounds; 设置YES 使得在layer上的子视图显示圆角有效
id contents; layer上的内容面,如图片
CGRect contentsRect; 显示的内容的区域 
NSString *contentsGravity; 跟UIView的ContentModel类似,显示的类型,是一个字符串。
CGFloat contentsScale 内容的缩放。 
CGRect contentsCenter; 显示内容的中心
NSString *contentsFormat 内容的格式
BOOL opaque; 是否不透明。默认是YES,也就是不透明的
float minificationFilterBias; 减小大小的因子
rasterizationScale 光栅化
@property(copy) NSString *minificationFilter;@property(copy) NSString *magnificationFilter; 缩小和放大时的描绘方式。

shadowColor

shadowOpacity

shadowOffset

shadowRadius

shadowPath

阴影的颜色

阴影透明度

阴影的偏移量

阴影的半径

阴影路径 。比如:可以画一个三角形的区域作为layer的路径,那显示的阴影就是三角形的。

needsDisplayOnBoundsChange

drawsAsynchronously

edgeAntialiasingMask

allowsEdgeAntialiasing

位置改变是否刷新

异步绘制

抗锯齿

放大之后是否允许抗锯齿

backgroundColor

borderWidth

borderColor

opacity

背景颜色

边框宽度

边框颜色

透明度设置

PS: 在设置layer 的阴影的时候,如果设置了layer的圆角的话,那么设置的阴影效果将不会显示出来。 一个解决办法是:在控件的下方添加一个相同的frame的底层控件,在底层空间上设置阴影,原控件可以设置圆角。

二、CALayer的使用

(1). 使用CALayer作出阴影效果

class ViewController: UIViewController {

    override func viewDidLoad() {
super.viewDidLoad()
let testVC:UIImageView = UIImageView.init(frame: CGRect.init(x: 10, y: 100, width: screenWidth-20, height: screenWidth-20))
testVC.image = #imageLiteral(resourceName: "timg.jpeg")
self.view.addSubview(testVC) //添加圆角
// testV.layer.cornerRadius = 30
// testV.layer.masksToBounds = true //添加阴影 注意:如果有圆角的话,阴影效果添加将会无效
testV.layer.shadowColor = UIColor.black.cgColor
testV.layer.shadowOpacity = 0.8
testV.layer.shadowRadius = 30;
testV.layer.shadowOffset = CGSize.init(width: 0, height: -1) //上述方式将使用离屏渲染,在性能上的消耗很大,为了加快渲染,我们添加下面的代码。
testVC.layer.shadowPath = UIBezierPath.init(rect: testVC.bounds).cgPath }

(2). 使用CALayer的子类CAShapeLayer绘制彩色的圆环

CAShapeLayer的特点是必须依赖路径才能显示,这样有助于我们绘制不同的形状用CAShapeLayer来显示。

 //使用CAShperlayer
func userShaper(){ //创建一个底色
let BgView:UIView = UIView.init(frame: CGRect.init(x: , y: , width: , height: ))
BgView.center = self.view.center
BgView.backgroundColor = UIColor.black
self.view.addSubview(BgView) let leftG : CAGradientLayer = CAGradientLayer.init()
leftG.colors = [UIColor.red.cgColor,UIColor.orange.cgColor,UIColor.yellow.cgColor]
leftG.locations = [,0.5,0.9]
leftG.startPoint = CGPoint.init(x: , y: )
leftG.endPoint = CGPoint.init(x: , y: 1.0)
leftG.frame = CGRect.init(x: , y: , width: , height: ) let rightG : CAGradientLayer = CAGradientLayer.init()
rightG.colors = [UIColor.blue.cgColor,UIColor.init(red: /255.0, green: 1.0, blue: /255.0, alpha: 1.0).cgColor,UIColor.green.cgColor,UIColor.yellow.cgColor]
rightG.locations = [,0.35,0.7,0.9]
rightG.startPoint = CGPoint.init(x: , y: )
rightG.endPoint = CGPoint.init(x: , y: 1.0)
rightG.frame = CGRect.init(x: , y: , width: , height: ) BgView.layer.addSublayer(leftG)
BgView.layer.addSublayer(rightG) let lineWidth:CGFloat = 10.0 //线宽
let CASharp:CAShapeLayer = CAShapeLayer.init()
CASharp.lineWidth = lineWidth
CASharp.lineCap = "round"
CASharp.lineJoin = "round" //包角为圆形 //创建路径
// let path : UIBezierPath = UIBezierPath.init(roundedRect: BgView.bounds, cornerRadius: 10.0)
// let rect:CGRect = CGRect.init(x: BgView.bounds.origin.x+width/2.0, y:BgView.bounds.origin.y+width/2.0, width: BgView.bounds.size.width-width, height: BgView.bounds.size.height-width)
//// let path : UIBezierPath = UIBezierPath.init(ovalIn: rect)
//
//起始角度
let path1:UIBezierPath = UIBezierPath.init(arcCenter:CGPoint.init(x: , y: ), radius: BgView.frame.width/2.0 - lineWidth, startAngle: -(CGFloat(Double.pi/2.0)), endAngle: CGFloat(Double.pi), clockwise: true) CASharp.strokeColor = UIColor.blue.cgColor
CASharp.path = path1.cgPath
CASharp.fillColor = UIColor.clear.cgColor BgView.layer.mask = CASharp print("完成")
}

下面是彩色环形的样子。  我们可以通过控制圆的起始位置来控制圆环的长度,如果做起动画就可以形成彩色环形控制条的效果。

三、UIView的绘制方法

我们在开发过程中,经常会涉及到修改控件上的显示内容。实际上,在修改内容之后,不会立即在屏幕上作出反应,而是等待一个runloop周期之后进行刷新。不过这个频率很快,我们肉眼认为几乎是即时修改的。有时候我们会主动的通过- (void)drawRect:(CGRect)rect来对UIView做一些修改,在上下文中绘制一些内容,但是这些内容不会自动显示,我们需要调用以下方法才可实现:

 - (void)setNeedsDisPlay

  调用此方法通知系统view需要重新绘制,会异步自动调用drawRect方法。

  - (void)setNeedsDisplayInRect:(CGRect)rect

  同样异步调用drawRect方法。在一次运行循环(run loop)中无论调用setNeedsDisplay或setNeedsDisplayInRect多少次,只调用drawRect一次。也是从减少资源开销的角度考虑的。

  - (void)drawRect:(CGRect)rect

  此方法的缺省实现是空。子类使用原生的绘制技术(Core Graphics and UIKit)绘制内容时应该重写此方法,在方法里面写出自己的drawing code。如果view设置自己的内容用其他的方法,则不需要去重写此方法。如果直接从UIView对象继承,实现此方法不需要call super。然而如果从其他的UIView对象继承,则应该调用super。当view 第一次显示或者当view的可视的一部分无效时,此方法会调用。此方法不能直接被调用。调用setNeedsDisplay 或者 setNeedsDisplayInRect: 方法会触发重新绘制。

UIView的绘制实际上就是对CALayer内容的修改。

最新文章

  1. 【Android】Eclipse自动编译NDK/JNI的三种方法
  2. mysql, count函数容易曲解的地方
  3. 301 redirect Domain Name using global.asax
  4. 使用苏飞httphelper开发自动更新发布文章程序
  5. centos7下yum安装mysql
  6. 可以用WMI来获取磁盘及分区编号
  7. 菜鸟学习Struts——总结
  8. mysql 错误代码汇总
  9. javascript循环
  10. Android开发之显示通知
  11. android的生命周期
  12. 控制 Memory 和 CPU 资源的使用
  13. RESTful WebService 入门实例
  14. Java集合之WeakHashMap
  15. 从非标准的POST数据流中提取文件
  16. 对div的操作
  17. iOS开发之--在UIWindow上展示/移除一个View
  18. JavaScript数组去重方法总结
  19. 【LeetCode】N数和
  20. linux操作系统重启后 解决nginx的pid消失问题

热门文章

  1. 接口如何使用(以笑话大全api为例)
  2. iOS_06_基本运算符
  3. 并发,two
  4. MySql 中的setAutoCommit方法
  5. UVA 11624 - Fire! 图BFS
  6. 【习题 5-11 UVA 12504 】Updating a Dictionary
  7. 一文看懂AI芯片竞争五大维度
  8. 【3002】删去K个数字
  9. python中有关字符串的处理
  10. 每天一个JavaScript实例-操作元素定位元素