//知识点,CALayer的重绘,-(void)drawLayer:(CALayer *)layer inContext:(CGContextRef)ctx 方法,CALayer的渐变色。多个CALayer重绘的方法。

//本例是一个,ViewController类,没有继承任何delegate,

也就是说下边的ca1,ca2,ca3的delegate直接设置为self,不用继承像<UITextFieldDelegate>这样的委托。CALyer好像没有委托,直接用就是了。不用搞清楚,直接写就是了。

//测试这个例子的随便建一个基于UIViewController类的,我选的是SingleViewApplication如图:

(独立的视图应用)第一排的第四个,随便起个名字,进去将所有的AnimationController(我的项目名)改成你自己的项目的名字。就可以运行了。

//还得添加一个QuartzCore.framework,怎么添加就不说了,已经说的很清楚了,哪里不会留言...

//怎么添加QuartzCore.framework还是说下吧:

//1,在左侧点击点击项目

//2,中间的位置往上拖一点,看到四个黄色的小工具箱,左下角有个加号,点击出来很多个黄色的小箱子,找到QuartzCore.framework 点Add。就添加进来了,然后在m文件中声明,这都是必要的过程,就像我的m文件里的#import <QuartzCore/QuartzCore.h>。

//h文件:

#import <UIKit/UIKit.h>

@interface AnimationController : UIViewController

//注意UIViewController后边没有<委托>;

@property (nonatomic, retain)CALayer *layer1;

@property (nonatomic, retain)CALayer *layer2;

@property (nonatomic, retain)CALayer *layer3;

//定义三个CALayer *layer1,*layer2,*layer3;

@end

//M文件:

#import "AnimationController.h"

#import <QuartzCore/QuartzCore.h>

@interface AnimationController ()

#define UIColorFromRGB(rgbValue) [UIColor colorWithRed:((float)((rgbValue & 0xFF0000) >>16))/255.0 green:((float)((rgbValue & 0xFF00) >> 8))/255.0 blue:((float)(rgbValue &0xFF))/255.0 alpha:1.0]

//这个地方是一个常量,用来设置RGB颜色,不用可以不写,我的例子用了,所以请你照抄,蛮有用处的,留着也可以以后用。

@end

@implementation AnimationController

@synthesize layer1 = _layer1;

@synthesize layer2 = _layer2;

@synthesize layer3 = _layer3;

//上边是3个CALayer类_layer1,_layer2,_layer3,就是h文件中的 *layer1; *layer2; *layer3,这个是IOS开发的机制,不解释;

- (void)viewDidLoad

{

[super viewDidLoad];

self.view.layer.backgroundColor = [UIColor whiteColor].CGColor;

//设置self.view.layer背景色。

CALayer *ca1 = [CALayer layer];

//实例化一个CALayer:ca1;

ca1.backgroundColor = [UIColor whiteColor].CGColor;

//设置ca1的背景颜色。

ca1.frame = CGRectMake(50, 500, 200, 200);

//设置ca1的frame(坐标和大小);

ca1.delegate = self;

//ca1.delegate = self;这一步非常重要,

ca1.name = @"fuck";

//这个ca1.name设置不设置都行,没有用到。

[ca1 setNeedsDisplay];

//ca1调用setNeedsDisplay,来绘制自己的页面。

CALayer *ca2 = [CALayer layer];

ca2.backgroundColor = [UIColor orangeColor].CGColor;

ca2.frame = CGRectMake(300, 500, 200, 200);

ca2.name = @"you";

ca2.delegate = self;

[ca2 setNeedsDisplay];

//ca2的和ca1没什么区别,就是颜色和坐标不同,还有name不同。

CALayer *ca3 = [CALayer layer];

ca3.backgroundColor = [UIColor yellowColor].CGColor;

ca3.frame = CGRectMake(550, 500, 200, 200);

ca3.name = @"man";

ca3.delegate = self;

[ca3 setNeedsDisplay];

//ca3的和ca1没什么区别,就是颜色和坐标不同,还有name不同。

[self.view.layer addSublayer:ca1];

//向self.view.layer添加ca1,记住一定要是self.view的layer中添加。

[self.view.layer addSublayer:ca2];

//向self.view.layer添加ca2

[self.view.layer addSublayer:ca3];

//向self.view.layer添加ca3

self.layer1 = ca1;

//将ca1赋值给self.layer1;

self.layer2 = ca2;

//将ca2赋值给self.layer2;

self.layer3 = ca3;

//将ca2赋值给self.layer3;

}

//这个方法是很重要的:-(void)drawLayer:(CALayer *)layer inContext:(CGContextRef)ctx,传进来两个参数(CALayer *)类型的layer和(CGContextRef)类型的ctx,也就是说我们在调用[ca1 setNeedsDisplay]的时候他传进来的layer==ca1因为我们将ca1赋值给了self.layer1所以layer也==self.layer1,ctx是ca1这个层的上下文,也就相当于是一个画板,让我们在上边重绘,这个方法就相当于UIView的:-(void)drawRect;方法,能理解理解,不能理解你就知道他就是传进来两个参数,一个层,一个画板,在我们调用[ca1 setNeedsDisplay]的时候;

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

{

NSLog(@"layer.name ==== %@",layer.name);

//输出当前的layer的name,可有可无,只是告诉我们当前是哪个layer。

if(layer == self.layer1)

//这里加一个判断,当layer是self.layer1的时候是一种重绘办法,也就是说三个层self.layer1,self.layer2,self.layer3你可能需要一个画树,一个画草,一个画小鸟,只是举个例子哦,我画不了小鸟的。我这里画的是,self.layer1:一个渐变的层,右上角画了一个灰色的三角符号,self.layer2:在一个层的右上角画了一个蓝色的三角符号,self.layer3:在一个层的右上角画了一个黑色的三角符号。

{

CGGradientRef myGradient;

CGColorSpaceRef myColorSpace;

size_t locationCount = 3;

CGFloat locationList[] = {0.0,0.1,1.0};

CGFloat colorList[]={

1.0,0.0,0.5,1.0,

1.0,0.0,1.0,1.0,

0.3,0.5,1.0,1.0,

};

myColorSpace = CGColorSpaceCreateDeviceRGB();

myGradient = CGGradientCreateWithColorComponents(myColorSpace, colorList, locationList, locationCount);//核心函数就是这个了,要搞清楚一些量化的东西了.

CGPoint startPoint,endPoint;

startPoint.x = 0;

startPoint.y = 0;

endPoint.x = CGRectGetMaxX(layer.bounds);

endPoint.y = CGRectGetMaxY(layer.bounds);

CGContextDrawLinearGradient(ctx, myGradient, startPoint, endPoint, 0);//这个是绘制的,你可以通过裁剪来完成特定形状的过度。

CGColorSpaceRelease(myColorSpace);

CGGradientRelease(myGradient);

CGContextSetLineCap(ctx, kCGLineCapSquare);

CGContextSetLineWidth(ctx, 1.0);

CGContextSetRGBStrokeColor(ctx, 1.0, 0.0, 0.0, 1.0);

//上边是设置层的渐变色的过程,代码具体我不讲了,没事自己研究研究IOS的一些绘画代码,以此为分割线,下边是画的一个简单的三角形。

CGContextBeginPath(ctx);

//开始一个路径

CGContextMoveToPoint(ctx, layer.bounds.size.width * 3/4,layer.bounds.origin.y + 1);

//设置一个起点坐标

CGContextAddLineToPoint(ctx, layer.bounds.size.width - 1, layer.bounds.origin.y + 1);

//移动到下一个点的坐标

CGContextAddLineToPoint(ctx, layer.bounds.size.width - 1, layer.bounds.size.width *1/4);

//移动到下一个点的坐标

CGContextAddLineToPoint(ctx, layer.bounds.size.width * 3/4, layer.bounds.origin.y +1);

//移动到下一个点的坐标

CGContextSetFillColorWithColor(ctx, UIColorFromRGB(0x555555).CGColor);

//设置填充色,这里就用到了我们上边定义的UIColorFromRGB()一般这个括号里输入的是(0x******)零x开头的后边是6位16进制的RGB颜色数,0x不变变换后边六位数就可以改变颜色,网上一搜一大把,或者我的博客里找有专门的RGB颜色网站集合。

CGContextFillPath(ctx);

//填充.

CGContextStrokePath(ctx);

//连接所有点,就成了一个三角形了。

}

if(layer == self.layer2)

{

CGContextSetLineCap(ctx, kCGLineCapSquare);

CGContextSetLineWidth(ctx, 1.0);

CGContextSetRGBStrokeColor(ctx, 1.0, 0.0, 0.0, 1.0);

CGContextBeginPath(ctx);

CGContextMoveToPoint(ctx, layer.bounds.size.width * 3/4,layer.bounds.origin.y + 1);

//设置一个起点坐标

CGContextAddLineToPoint(ctx, layer.bounds.size.width - 1, layer.bounds.origin.y + 1);

//移动到下一个点的坐标

CGContextAddLineToPoint(ctx, layer.bounds.size.width - 1, layer.bounds.size.width *1/4);

//移动到下一个点的坐标

CGContextAddLineToPoint(ctx, layer.bounds.size.width * 3/4, layer.bounds.origin.y +1);

//移动到下一个点的坐标

CGContextSetFillColorWithColor(ctx, UIColorFromRGB(0x8F9FEA).CGColor);

CGContextFillPath(ctx);

CGContextStrokePath(ctx);

//这个和self.layer1的画三角一样,只是我改变了他的RGB便于区别。

//把这些坐标连起来

}

if(layer == self.layer3)

{

CGContextSetLineCap(ctx, kCGLineCapSquare);

CGContextSetLineWidth(ctx, 1.0);

CGContextSetRGBStrokeColor(ctx, 1.0, 0.0, 0.0, 1.0);

CGContextBeginPath(ctx);

CGContextMoveToPoint(ctx, layer.bounds.size.width * 3/4,layer.bounds.origin.y + 1);

//设置一个起点坐标

CGContextAddLineToPoint(ctx, layer.bounds.size.width - 1, layer.bounds.origin.y + 1);

//移动到下一个点的坐标

CGContextAddLineToPoint(ctx, layer.bounds.size.width - 1, layer.bounds.size.width *1/4);

//移动到下一个点的坐标

CGContextAddLineToPoint(ctx, layer.bounds.size.width * 3/4, layer.bounds.origin.y +1);

//移动到下一个点的坐标

CGContextSetFillColorWithColor(ctx, UIColorFromRGB(0x000000).CGColor);

CGContextFillPath(ctx);

CGContextStrokePath(ctx);

//这个和self.layer2的画三角一样,也只是改变了颜色。

}

}

@end
 
运行结果是这样的:
弄了很久,想方便你们,拿走请注明出处。

同一个页面多个CALayer重绘的办法的更多相关文章

  1. 页面优化,谈谈重绘(repaint)和回流(reflow)

    一.前言 偶尔在面试过程中遇到过重汇与回流reflow的问题,毕竟页面优化也是考核一个开发者能力的关键之一,上篇文章聊了下documentfragment也是为了减轻回流问题,那么本篇文章好好介绍下重 ...

  2. 介绍回流与重绘(Reflow & Repaint),以及如何进行优化?

    前言 回流与重绘对于前端来说可以说是非常重要的知识点了,我们不仅需要知道什么是回流与重绘,还需要知道如何进行优化.一个页面从加载到完成,首先是构建DOM树,然后根据DOM节点的几何属性形成render ...

  3. Web前端性能优化-重绘与回流

    1.什么是重绘与回流 Render tree 的重新构建就叫回流.当布局和几何属性改变时就需要回流,鼠标移动到图片 图片变大 也会触发回流.回流 能避免就避免 Render tree 改变外观.风格 ...

  4. 160826、浏览器渲染页面过程描述,DOM编程技巧以及重排和重绘

    一.浏览器渲染页过程描述   1.浏览器解析html源码,然后创建一个DOM树. 在DOM树中,每一个HTML标签都有一个对应的节点(元素节点),并且每一个文本也都有一个对应的节点(文本节点). DO ...

  5. 浏览器渲染页面过程描述,DOM编程技巧以及重排和重绘。

    一.浏览器渲染页过程描述 1.浏览器解析html源码,然后创建一个DOM树. 在DOM树中,每一个HTML标签都有一个对应的节点(元素节点),并且每一个文本也都有一个对应的节点(文本节点). DOM树 ...

  6. 【web性能】页面呈现、重绘、回流

    在讨论页面重绘.回流之前.需要对页面的呈现流程有些了解,页面是怎么把html结合css等显示到浏览器上的,下面的流程图显示了浏览器对页面的呈现的处理流程.可能不同的浏览器略微会有些不同.但基本上都是类 ...

  7. 页面重绘(repaint)和回流(reflow)

    前言 页面显示到浏览器上的过程: 1.1.生成一个DOM树. 浏览器将获取到的HTML代码解析成1个DOM树,包含了所有标签,包括display:none和动态添加的节点. 1.2.生成样式结构体. ...

  8. HTML页面的重绘(repaint)和重流(reflow)

    重流(Reflow)是指布局引擎为frame计算图形的过程. frame是一个矩形,拥有宽高和相对父容器的偏移.frame用来显示盒模型(content model), 但一个content mode ...

  9. 高性能WEB开发:深入理解页面呈现、重绘、回流

    在讨论页面重绘.回流之前.需要对页面的呈现流程有些了解,页面是怎么把html结合css等显示到浏览器上的,下面的流程图显示了浏览器对页面的呈现的处理流程.可能不同的浏览器略微会有些不同.但基本上都是类 ...

随机推荐

  1. java接口传递数据的实例

    我们要讲E类中的数据变化通知A类,这样通过接口F来实现.具体原理就是E的每次数据改变都让其通知接口:而A类继承接口,所以每次E的调用接口都会触发A类的数据更改事件的触发. 首先创建一个类E: publ ...

  2. 将16进制(HTML)颜色值转换成 Color类型

    private void btnChangeColor_Click(object sender, EventArgs e) { txtColor.BackColor = ColorTranslator ...

  3. C#编写Windows服务程序图文教程(转载)

    Windows Service这一块并不复杂,但是注意事项太多了,网上资料也很凌乱,偶尔自己写也会丢三落四的.所以本文也就产生了,本文不会写复杂的东西,完全以基础应用的需求来写,所以不会对Window ...

  4. js、java传值编码

    一.请求使用post方法不需要考虑编码问题.二.前后台统一编码,支持中文,不考虑编码:tomcat utf-8编码三.前后台编码不统一 $.ajax({                url : &q ...

  5. linux 虚拟机centos64位_6.5+VM10 主机是固定IP局域网设置代理上网,虚机设置固定ip 图文详细步骤

    一种: 虚机是Desktop 安装 1.虚拟机—设置—网络适配器子选项—选择“桥接模式” 2.在虚拟机中选择系统(System)—首选项(Preferences)—网络连接(Network Conne ...

  6. 基于Pojo的开发模式(day03)

    上一次的文章讨论到了Spring的设计目标:使得JEE开发更易用. ok,作为一个Java开发人员,应该都知道struts这个框架,不知道是否大家都清楚struts1和struts2的区别. 首先,这 ...

  7. 用Java来比较JavaScript的一些特性

    由于是从java做到JavaScript,所以对强弱语言类型,还是比较敏感的.JavaScript是弱语言,只严格区分数据和指令.简单描述下自己对两者之间的一些区别吧. 1.JavaScript变量的 ...

  8. 关于extern对变量的使用

    extern 是声明全局的变量的意思. 例如在一个工程中有两个cpp,一个是test.cpp一个是main.cpp . 我们在test.cpp中定义了一个int num;但是我们在main.cpp中想 ...

  9. Server.MapPath() 解析

    Server.MapPath获得的路径都是服务器上的物理路径,也就是常说的绝对路径 ./当前目录 /网站主目录 ../上层目录 ~/网站虚拟目录 1.Server.MapPath("/&qu ...

  10. [POJ] 2453 An Easy Problem [位运算]

    An Easy Problem   Description As we known, data stored in the computers is in binary form. The probl ...