`

用CALayer绘图

阅读更多

在iOS中绘图,可以使用UIView,也可以使用CALayer。实际上,UIView也是由底层的CALayer完成绘制的工作
<!--more-->

UIView和CALayer的关系

每个UIView内部都有一个CALayer对象,由它来完成绘制的工作。和view一样,layer也是一个树形的结构

当不需要自定义组件的时候,用UIView的API就足以胜任,把需要的子view通过addSubview()方法放到view的层次里即可;但是如果需要自己绘制一些图形,就需要在UIView的drawRect()方法或是CALayer的相关方法中,调用CoreGraphics的API来画图

跟几个朋友也讨论过这个问题,我认为用layer来画是更好的办法,因为相对于view,layer是更轻量级的组件,可以节省系统资源。同时layer是动画的基本单元,加动画特效也更容易。并且view负责响应手势等,把绘制的代码都放在layer里,逻辑上也更加清晰

但是需要注意,layer不能直接响应触摸事件,所以手势识别还是需要通过view来完成

在UIView中绘图

在UIView中绘图非常简单,当调用

self.setNeedsDisplay()

iOS系统会自动调用view上的drawRect()方法,可以在drawRect()方法中绘制图形

在CALayer中绘图

在layer中绘图,生命周期比view复杂一些

首先也是调用layer上的setNeedsDisplay()触发的

display

首先会进入layer的display()方法,在这里可以把CGImage赋给layer的contents,那么会直接把该CGImage作为此layer的样式,不会进入后续的方法

// 绘图方法
override func display() {

    if let img = getFrameImage(wheelStyle) {
        contents = img.CGImage
    }        
}

displayLayer

如果没有实现display()方法,或者调用了super.display(),并且设置了layer的delegate,那么iOS系统会调用delegate的displayLayer()方法

let myLayer : MyLayer = MyLayer()
myLayer.delegate = self;
myLayer.frame = bounds;
override func displayLayer(layer: CALayer) {

    if let img = getFrameImage(wheelStyle) {
        contents = img.CGImage
    }
}

drawInContext

如果没有设置delegate,或者delegate没有实现displayLayer()方法,那么接下来会调用layer的drawInContext方法

override func drawInContext(ctx: CGContext) {

    CGContextSetLineWidth(ctx, 1);
    CGContextMoveToPoint(ctx, 80, 40);
    CGContextAddLineToPoint(ctx, 80, 140);
    CGContextStrokePath(ctx);
}

drawLayerInContext

如果layer没有实现drawInContext方法,那么接下来就会调用delegate的drawLayerInContext方法

override func drawLayer(layer: CALayer, inContext ctx: CGContext) {
    CGContextSetLineWidth(ctx, 1);
    CGContextMoveToPoint(ctx, 80, 40);
    CGContextAddLineToPoint(ctx, 80, 140);
    CGContextStrokePath(ctx);
}

总结

所以,一般来说,可以在layer的display()或者drawInContext()方法中来绘制

在display()中绘制的话,可以直接给contents属性赋值一个CGImage,在drawInContext()里就是各种调用CoreGraphics的API

假如绘制的逻辑特别复杂,希望能从layer中剥离出来,那么可以给layer设置delegate,把相关的绘制代码写在delegate的displayLayer()和drawLayerInContext()方法。这2个方法与display()和drawInContext()是分别一一对应的

<script type="text/javascript"> $(function () { $('pre.prettyprint code').each(function () { var lines = $(this).text().split('\n').length; var $numbering = $('<ul/>').addClass('pre-numbering').hide(); $(this).addClass('has-numbering').parent().append($numbering); for (i = 1; i <= lines; i++) { $numbering.append($('<li/>').text(i)); }; $numbering.fadeIn(1700); }); }); </script>
分享到:
评论

相关推荐

    ios-自定义CALayer.zip

    通过自定义CALayer,实现星空模拟效果(当然效果一般般)。代码很简单,都在CMLayer类中,仅为大家自定义CALayer并添加相关动画提供一份参考demo。

    iOS开发中CALayer使用的基本教程

    一、简单介绍 在iOS中,你能看得见摸得着的东西基本上都是UIView,比如一个按钮...当UIView需要显示到屏幕上时,会调用drawRect:方法进行绘图,并且会将所有内容绘制在自己的图层上,绘图完毕后,系统会将图层拷贝到屏

    ios-CALayer.zip

    基础用法,方便学习,满足需求。

    iOS优雅的将CALayer旋转360度示例代码

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

    swift-ZMCALayerAnimationiOS绘图和动画

    ZM_CALayerAnimation iOS绘图和动画

    IOS 中CALayer绘制图片的实例详解

    主要介绍了IOS 中CALayer绘制图片的实例详解的相关资料,希望通过本文能帮助到大家,需要的朋友可以参考下

    ios-图片遮罩层-Swift.zip

    1、CALayer 、 CAShapeLayer 什么是CALayer? CALayer(这里简单地称其为层)。 首先要说的是CALayers 是屏幕上的一个具有可见内容的矩形区域,每个UIView都有一个根CALayer ...使用UIBezierPath绘制图形

    Touchvg:TouchVG 是一个主要由C++开发的轻量级2D矢量绘图框架,可在 iOS、Android、Windows 等多个平台构建矢量绘图应用

    高性能绘图、快速手绘光滑曲线形状,在 iOS 上支持 CALayer 后台渲染和动态并行渲染,在 Android 上支持 SurfaceView 异步渲染。 除了基本的15余种矢量图形类型外,可使用C++或Java等来扩充更多的图形类型。 除了...

    ios-折线图、柱状图、饼状图.zip

    利用CALayer 画折线图、柱状图、饼状图

    RippleLayer:绘图飞溅效果

    波纹层概述使用CGPath绘制飞溅效果。 灵感 。 原始算法是例子要运行示例项目,请克隆存储库,然后首先从Example目录运行pod install 。入门安装RippleLayer可通过。 要安装它,只需将以下行添加到您的Podfile中: ...

    iOS实现轮盘动态效果

    最后用了一个定时器实现类似效果,总感觉不太明智,以后应该考虑下对CALayer和 隐式动画的角度考虑下 #import /** * 自定义变量里面以s结尾的表示具体的数值,否则表示的是表示显示具体内容的标签,以lbe的表示对...

    ios-自定义图片显示.zip

    通过类目和自定义CALayer子类绘制layer作为其他layer的mask,并添加图片显示

    逐行刷新式更换UIImage(iPhone源代码)

    代码使用CAlayer完成。 小编注:这是作者更新的最新代码,解决之前代码的bug,目前可以连续点击更换图片按钮,没有刷新完成的图片会瞬间加载完成,然后重新加载新图片。感谢作者@石桥楊峰 分享代码于Code4App。 ...

    RoughSwift:Swift在Swift中创建手绘的,粗略的,喜剧的形状

    基于的相同概念(生成可高度组合和可变的CALayer ,RoughSwift将绘图命令转换为漂亮的粗略图形。 支持iOS,tvOS 支持macOS 支持所有形状:直线,矩形,圆形,椭圆形,线性路径,弧形,曲线,多边形,svg路径 ...

    ios-动态折线图统计图.zip

    利用calayer等实现简单的动态折线统计图; 下载地址:https://github.com/mayi977/Grid-BrokenLine

    纹理:适用于iOS应用程序的平滑异步用户界面

    与只能在主线程上使用的视图不同,节点是线程安全的:您可以在后台线程上并行实例化和配置它们的整个层次结构。 为保持其用户界面流畅和响应速度,您的应用应以每秒60帧的速度渲染-这是iOS上的黄金标准。 这意味着...

Global site tag (gtag.js) - Google Analytics