CALayer 基础

UIView在ios开发里面是非常重要的。几乎所有的控件都是从UIView继承下来的。比如UILabel,UIText等。

今天有空看了一下UIView的内部结构。发现其实UIView的显示部分其实委托给CALayer(Core Animation Layer)来做的。

UIView类片段

NS_CLASS_AVAILABLE_IOS(2_0) @interface UIView : UIResponder <NSCoding, UIAppearance, UIAppearanceContainer, UIDynamicItem, UITraitEnvironment, UICoordinateSpace> {
  @package
    CALayer        *_layer;
    id              _gestureInfo;
    NSMutableArray *_gestureRecognizers;
    NSArray        *_subviewCache;
    float           _charge;
    NSInteger       _tag;
    UIViewController *_viewDelegate;
    NSString         *_backgroundColorSystemColorName;
    NSUInteger      _countOfMotionEffectsInSubtree;

里面有个CALayer的成员。

CALayer的主要功能就是在屏幕上显示东西了。

CALayer属性

我们可以通过CALayer的属性来改变图层的一些外观。

- (IBAction)btnClick:(id)sender {
    CALayer *sublayer =[CALayer layer];
    sublayer.backgroundColor =[UIColor blueColor].CGColor;
    sublayer.shadowOffset = CGSizeMake(0, 3);
    sublayer.shadowRadius =5.0;
    sublayer.shadowColor =[UIColor blackColor].CGColor;
    sublayer.shadowOpacity = 1;
    sublayer.frame = CGRectMake(150, 20, 128, 50);
    sublayer.borderColor =[UIColor blackColor].CGColor;
    sublayer.borderWidth =2.0;
    sublayer.cornerRadius =10.0;
    sublayer.anchorPoint = CGPointMake(0, 0);
    [self.view.layer addSublayer:sublayer];

    CABasicAnimation *animation = [ CABasicAnimation animationWithKeyPath: @"transform" ];
    animation.toValue = [ NSValue valueWithCATransform3D: CATransform3DMakeRotation(3.1415, 0, 0, 1.0) ];
    animation.duration = 2;
    animation.cumulative = YES;
    animation.repeatCount = 2;
    [sublayer addAnimation: animation forKey: @"animation" ];

}

上面的代码主要分几部分:

1. 创建一个CALayer的实例

2. 修改一些属性,比如阴影,圆角等。

3. 把新创建的CALayer实例加到当前view的层里面,作为子层。

4. 给新创建的CALayer实例增加一个动画效果。

点一下第一个按钮,就会发现有个蓝色的图层(CALayer),会旋转一圈。这些都是刚才的那些代码做的事情,非常简单。

CALayer显示图片

在ios上显示一张图片其实很简单,搞个ImageView控件就可以了。

实际上ImageView也是从UIView继承下来的,其实也是通过CALayer显示的。那么如果使用CALayer直接显示一张图片呢?

通过下面的代码就可以搞定了:

- (IBAction)btnContent:(id)sender {
    CALayer *sublayer =[CALayer layer];
    sublayer.backgroundColor =[UIColor orangeColor].CGColor;
    sublayer.shadowOffset = CGSizeMake(0, 3);
    sublayer.shadowRadius =5.0;
    sublayer.shadowColor =[UIColor blackColor].CGColor;
    sublayer.shadowOpacity = 1;

    sublayer.borderColor =[UIColor blackColor].CGColor;
    sublayer.borderWidth =2.0;
    sublayer.cornerRadius =10.0;
    sublayer.anchorPoint = CGPointMake(0, 0);
    [self.view.layer addSublayer:sublayer];

    CGImageRef img = [UIImage imageNamed:@"Image"].CGImage;
    sublayer.contents = (__bridge id)img;
    sublayer.frame = CGRectMake(180, 60, CGImageGetWidth(img), CGImageGetWidth(img));

    CABasicAnimation *animation = [ CABasicAnimation animationWithKeyPath: @"transform" ];
    animation.toValue = [ NSValue valueWithCATransform3D: CATransform3DMakeRotation(3.1415, 0, 0, 1.0) ];
    animation.duration = 2;
    animation.cumulative = YES;
    animation.repeatCount = 2;
    [sublayer addAnimation: animation forKey: @"animation" ];
}

代码也分几个部分

1. 创建一个新的CALayer对象

2. 设置一些属性

3. 把这个新创建的对象加到当前的view的CALayer里面。

4. 获取一张图片对象,赋给CALayer的contents

5. 跟前面一样,加个动画。

运行一下:

从截图里可以看到图片显示出来了(qq头像),并且有个旋转的动画效果。

CALayer是可以叠加的,如果有多个图片,那么就可以创建多个CALayer对象,一个个叠上去,同时还可以设置一些动画效果啥的。

比如,一个view消失的时候,我们可以放一些玻璃碎片图片上去,给每个CALayer对象加个掉下来的动画,这样看起来就像是玻璃破碎一样。

CALayer自定义绘画

除了简单修改CALayer对象属性和显示一张图片外,我们还可以自己绘制图层的内容。

先给出代码:

- (IBAction)btnCustomDraw:(id)sender {
    CALayer *customDrawn = [CALayer layer];
    customDrawn.delegate = self;
    customDrawn.backgroundColor = [UIColor greenColor].CGColor;
    customDrawn.frame = CGRectMake(180, 100, 128, 40);
    customDrawn.shadowOffset = CGSizeMake(0, 3);
    customDrawn.shadowRadius = 5.0;
    customDrawn.shadowColor = [UIColor blackColor].CGColor;
    customDrawn.shadowOpacity = 0.8;
    customDrawn.cornerRadius = 10.0;
    customDrawn.borderColor = [UIColor blackColor].CGColor;
    customDrawn.borderWidth = 2.0;
    customDrawn.masksToBounds = YES;
    [self.view.layer addSublayer:customDrawn];
    [customDrawn setNeedsDisplay];
}

void MyDrawColoredPattern (void *info, CGContextRef context) {

    CGColorRef dotColor = [UIColor colorWithHue:0 saturation:0 brightness:0.07 alpha:1.0].CGColor;
    CGColorRef shadowColor = [UIColor colorWithRed:1 green:1 blue:1 alpha:0.1].CGColor;

    CGContextSetFillColorWithColor(context, dotColor);
    CGContextSetShadowWithColor(context, CGSizeMake(0, 1), 1, shadowColor);

    CGContextAddArc(context, 3, 3, 4, 0, 3.14, 0);
    CGContextFillPath(context);

    CGContextAddArc(context, 16, 16, 4, 0, 3.14, 0);
    CGContextFillPath(context);

}

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

    CGColorRef bgColor = [UIColor colorWithHue:0.6 saturation:1.0 brightness:1.0 alpha:1.0].CGColor;
    CGContextSetFillColorWithColor(context, bgColor);
    CGContextFillRect(context, layer.bounds);

    static const CGPatternCallbacks callbacks = { 0, &MyDrawColoredPattern, NULL };

    CGContextSaveGState(context);
    CGColorSpaceRef patternSpace = CGColorSpaceCreatePattern(NULL);
    CGContextSetFillColorSpace(context, patternSpace);
    CGColorSpaceRelease(patternSpace);

    CGPatternRef pattern = CGPatternCreate(NULL,
                                           layer.bounds,
                                           CGAffineTransformIdentity,
                                           24,
                                           24,
                                           kCGPatternTilingConstantSpacing,
                                           true,
                                           &callbacks);
    CGFloat alpha = 1.0;
    CGContextSetFillPattern(context, pattern, &alpha);
    CGPatternRelease(pattern);
    CGContextFillRect(context, layer.bounds);
    CGContextRestoreGState(context);
}

创建CALayer对象那部分代码和前面的很相似,唯一的区别就是设置了一个委托

customDrawn.delegate = self;

我们需要实现一个drawLayer的函数。这个函数是个非正式协议,也就是NSObject的类别,所以所有的OC对象都有这个函数的声明。看下面的代码,可以清楚的看到这函数。

@interface NSObject (CALayerDelegate)

/* If defined, called by the default implementation of the -display
 * method, in which case it should implement the entire display
 * process (typically by setting the `contents' property). */

- (void)displayLayer:(CALayer *)layer;

/* If defined, called by the default implementation of -drawInContext: */

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

/* Called by the default -layoutSublayers implementation before the layout
 * manager is checked. Note that if the delegate method is invoked, the
 * layout manager will be ignored. */

- (void)layoutSublayersOfLayer:(CALayer *)layer;

/* If defined, called by the default implementation of the
 * -actionForKey: method. Should return an object implementating the
 * CAAction protocol. May return 'nil' if the delegate doesn't specify
 * a behavior for the current event. Returning the null object (i.e.
 * '[NSNull null]') explicitly forces no further search. (I.e. the
 * +defaultActionForKey: method will not be called.) */

- (id<CAAction>)actionForLayer:(CALayer *)layer forKey:(NSString *)event;

@end

我们实现了drawLayer这个函数后,那么就可以在里面自己来画东西了。通常都是使用core graphics来画的。

运行结果:

基本上有关CALayer的绘制就这么几种吧

1. 最简单的设置属性

2. 显示图片

3. 自定义绘制。

有了这些基础后,配合动画就可以做一些比较炫的ui界面了。

动画和core graphics后面有机会再研究。

时间: 2024-11-09 09:51:30

CALayer 基础的相关文章

OC - 21.CALayer核心要点及实例解析

CALayer基础 CALayer是每一个UI控件的核心,一个UI控件之所以能显示可以说是CALayer的功劳 每一个UI控件默认都为自己创建一个CALayer对象,通过drawRect方法将内容绘制在图层上,然后再显示出来 CALayer可以完成很多任务 调整UI控件的外观 执行动画 CALayer与UIView 二者可以达到相同的显示效果 UIView比CALayer多了用户交互功能 CALayer更加轻量级,性能更好 CALayer在系统架构中的位置 CALayer位于QuartzCore

iOS动画浅汇

转自:http://www.cocoachina.com/ios/20160311/15660.html 在iOS开发中,制作动画效果是最让开发者享受的环节之一.一个设计严谨.精细的动画效果能给用户耳目一新的效果,吸引他们的眼光 —— 这对于app而言是非常重要的.我们总是追求更为酷炫的实现,如果足够仔细,我们不难发现一个好的动画通过步骤分解后本质上不过是一个个简单的动画实现.本文就个人搜集的一些动画相关的理论和实践知识做个小结,不足之处请勿见怪. 理论 UIview VS UIlayer UI

iOS动画浅汇(转)

转自:http://www.cocoachina.com/ios/20160311/15660.html 在iOS开发中,制作动画效果是最让开发者享受的环节之一.一个设计严谨.精细的动画效果能给用户耳目一新的效果,吸引他们的眼光 —— 这对于app而言是非常重要的.我们总是追求更为酷炫的实现,如果足够仔细,我们不难发现一个好的动画通过步骤分解后本质上不过是一个个简单的动画实现.本文就个人搜集的一些动画相关的理论和实践知识做个小结,不足之处请勿见怪. 理论 UIview VS UIlayer UI

IOS SDK详解

来源:http://blog.csdn.net/column/details/huangwenchen-ios-sdk.html?page=1#42803301 博客专栏>移动开发专栏>IOS SDK详解 分享到:新浪微博腾讯微博IOS SDK详解 本专栏从IOS SDK中常用的Framework出发,继而深入的介绍各个Framework.每个Framework博主都会进行Demo 收藏 订阅 最新更新文章 [移动开发] IOS SDK详解之CALayer(二) 原创Blog,转载请注明出处

IOS动画(Core Animation)总结 (参考多方文章)

一.简介 iOS 动画主要是指Core Animation框架.官方使用文档地址为:Core Animation Guide. Core Animation是IOS和OS X平台上负责图形渲染与动画的基础框架.Core Animation可以作用与动画视图或者其他可视元素,为你完成了动画所需的大部分绘帧工作.你只需要配置少量的动画参数(如开始点的位置和结束点的位置)即可使用Core Animation的动画效果.Core Animation将大部分实际的绘图任务交给了图形硬件来处理,图形硬件会加

java web 开发三剑客 -------电子书

Internet,人们通常称为因特网,是当今世界上覆盖面最大和应用最广泛的网络.根据英语构词法,Internet是Inter + net,Inter-作为前缀在英语中表示“在一起,交互”,由此可知Internet的目的是让各个net交互.所以,Internet实质上是将世界上各个国家.各个网络运营商的多个网络相互连接构成的一个全球范围内的统一网,使各个网络之间能够相互到达.各个国家和运营商构建网络采用的底层技术和实现可能各不相同,但只要采用统一的上层协议(TCP/IP)就可以通过Internet

iOS面试必备-iOS基础知识

近期为准备找工作面试,在网络上搜集了这些题,以备面试之用. 插一条广告:本人求职,2016级应届毕业生,有开发经验.可独立开发,低薪求职.QQ:895193543 1.简述OC中内存管理机制. 答:内存管理机制:使用引用计数管理,分为ARC和MRC,MRC需要程序员自己管理内存,ARC则不需要.但是并不是 所有对象在ARC环境下均不需要管理内存,子线程和循环引用并不是这样.与retain配对使用的是release,retain代表引用计 数+1,release代表引用计数-1,当引用计数减为0时

GIF动画,菊花动画,UIView动画,CoreAnimation动画(CALayer动画)的用法

1.GIF动画 1 // 创建一个显示图片的imageView // viewController创建 2 UIImageView *showGifImageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 414, 736)]; 3 [self.view addSubview:showGifImageView]; 4 5 6 //创建一个存储图片的数组 7 NSMutableArray *saveImageViewArray

iOS_核心动画CALayer(一)

目 录: 一.核心动画简介 二.图层与视图之间的关系 三.CALayer的使用说明 四.CALayer的隐式动画属性 五.在CALayer上绘图 六.总结 一.核心动画简介 Core Animation 是跨平台的,支持iOS环境和Mac OS X环境,而CALayer是核心动画的基础,可以帮助开发者做圆角.阴影.边框等效果.我们学习核心动画之前,需要先理解CALayer,因为核心动画操作的对象不是UIView,而是CALayer.对于UIView控件每个内部都有一个Layer的属性.我们在实现