CoreAnimation编程指南(五)图层内容

当我们使用Cocoa的视图的时候,我们必须继承NSView或者UIView并且重载函数drawRect:来显示任何内容。但是CALayer实例可以直接使用,而无需继承子类。因为CALayer是一个键-值编码兼容的容器类,你可以在实例里面存储任意值,所以子类实例化完全可以避免。

1.1 给CALayer提供内容

  你可以通过以下任何一种方法指定CALayer实例的内容:
  (1)使用包含图片内容的CGImageRef来显式的设置图层的contents的属性。
  (2)指定一个委托,它提供或者重绘内容。
  (3)继承CALayer类重载显示的函数。

1.1.1 设置contents属性

  图层的图片内容可以通过指定contents属性的值为CGImageRef。当图层被创建的时候或者在任何其他时候,这个操作可以在其他实体上面完成(如表3所示)。 
  代码 1 设定layer的contents属性
  CALayer *theLayer;

  // create the layer and set the bounds and position
  theLayer=[CALayer layer];
  theLayer.position=CGPointMake(50.0f,50.0f);
  theLayer.bounds=CGRectMake(0.0f,0.0f,100.0f,100.0f);

  // set the contents property to a CGImageRef
  // specified by theImage (loaded elsewhere)
  theLayer.contents=theImage;
 
1.1.2 通过委托提供内容

  你可以绘制图层的内容,或更好的封装图层的内容图片,通过创建一个委托类实现下列方法之一:
  displayLayer:或drawLayer:inContext:
  
  实现委托重绘的方法并不意味会自动的触发图层使用实现的方法来重绘内容。而是你要显式的告诉一个图层实例来重新缓存内容,通过发送以下任何一个方法setNeedsDisplay或者setNeedsDisplayInRect:的消息,或者把图层的needsDisplayOnBoundsChange属性值设置为YES。
  
  通过委托实现方法displayLayer:可以根据特定的图层决定显示什么图片,还可以更加需要设置图层的contents属性值。下面的例子是“图层的坐标系”部分的,它实现displayerLayer:方法根据state的值设置theLayer的contents属性。子类不需要存储state的值,因为CALayer的实例是一个键-值编码容器。

  代码 2  委托方法displayLayer:的实现示例
  - (void)displayLayer:(CALayer *)theLayer
  {
      // check the value of the layer's state key
      if ([[theLayer valueForKey:@"state"] boolValue])
      {
          // display the yes image
          theLayer.contents=[someHelperObject loadStateYesImage];
      }
      else {
          // display the no image
          theLayer.contents=[someHelperObject loadStateNoImage];
      }
  }
 
  如果你必须重绘图层的内容,而不是通过加载图片,那你需要实现drawLayer:inContext:方法。通过委托可以决定哪些内容是需要的并使用CGContextRef来重绘内容。

  下面的例子是“指定图层的几何”部分内容,它实现了drawLayer:inContext:方法使用lineWidth键值来重绘一个路径(path),返回therLayer。
 
  代码 3  代理方法drawLayer:inContext:的实现示例
  - (void)drawLayer:(CALayer *)theLayer inContext:(CGContextRef)theContext
  {
    CGMutablePathRef thePath = CGPathCreateMutable();

    CGPathMoveToPoint(thePath,NULL,15.0f,15.f);
    CGPathAddCurveToPoint(thePath,
                          NULL,
                          15.f,250.0f,
                          295.0f,250.0f,
                          295.0f,15.0f);

    CGContextBeginPath(theContext);
    CGContextAddPath(theContext, thePath );

    CGContextSetLineWidth(theContext,
                          [[theLayer valueForKey:@"lineWidth"] floatValue]);
    CGContextStrokePath(theContext);

    // release the path
    CFRelease(thePath);
  }
 
1.1.3 通过子类提供图层的内容

  虽然通常情况不需要这样做,但是你仍可以继承CALayer直接重载重绘和显示方法。这个通常发生在你的图层需要定制行为而委托又无法满足需求的时候。

  子类可以重载CALayer的显示方法,设置图层的内容为适当的图片。下面的例子是“变换图层的几何”部分的内容,它提供了和“图层的坐标系”例子相同的功能。不同的是子类定义state为实例的属性,而不是根据CALayer的键-值编码容器获取。
 
  代码 4  CALayer display 方法的覆盖示例
  - (void)display
  {
    // check the value of the layer's state key
    if (self.state)
    {
        // display the yes image
        self.contents=[someHelperObject loadStateYesImage];
    }
    else {
        // display the no image
        self.contents=[someHelperObject loadStateNoImage];
    }
  }
 
  CALayer子类可以通过重载drawInContext:绘制图层的内容到一个图形上下文。下面的例子是“修改变换的数据结构”的内容,它和“指定图层的几何”里面实现委托的办法一样产生相同的图片内容。唯一的不同的是实现委托里面的lineWidth和lineColor现在是子类实例的属性。

  Listing 5  覆盖layer的drawInContext:方法示例
  - (void)drawInContext:(CGContextRef)theContext
  {
    CGMutablePathRef thePath = CGPathCreateMutable();

    CGPathMoveToPoint(thePath,NULL,15.0f,15.f);
    CGPathAddCurveToPoint(thePath,
                          NULL,
                          15.f,250.0f,
                          295.0f,250.0f,
                          295.0f,15.0f);

    CGContextBeginPath(theContext);
    CGContextAddPath(theContext, thePath );

    CGContextSetLineWidth(theContext,
                          self.lineWidth);
    CGContextSetStrokeColorWithColor(theContext,
                                     self.lineColor);
    CGContextStrokePath(theContext);
    CFRelease(thePath);
  }
  
  继承CALayer并且实现其中的重绘方法并不意味重绘会自动发生。你必须显式的促使实例重新缓存其内容,可以通过发送以下任何一个方法setNeedsDisplay或setNeedsDisplayInRect:的消息,亦或者设置图层的needsDisplaOnBoundsChange属性为YES。
 
1.2 修改图层内容的位置

  CALayer的属性contentsGravity允许你在图层的边界内容修改图层的contents图片的位置或者伸缩值。默认情况下,内容的图像完全填充层的边界,忽视自然的图像宽高比。

  使用contentsGravity位置常量,你可以指定图片位于图层任何一个边界,比如位于图层的角落,或者图层边界的中心。然而当你使用位置常量的时候,contentsCenter属性会被忽略。表1列举了位置常量和他们相应的位置。
   
  layer的contentsGravity属性的定位常量
  kCAGravityTopLeft
    Positions the content image in the top left corner of the layer.
  kCAGravityTop
    Positions the content image horizontally centered along the top edge of the layer.
  kCAGravityTopRight
    Positions the content image in the top right corner of the layer.
  kCAGravityLeft
    Positions the content image vertically centered on the left edge of the layer.
  kCAGravityCenter
    Positions the content image at the center of the layer.
  kCAGravityRight
    Positions the content image vertically centered on the right edge of the layer.
  kCAGravityBottomLeft
    Positions the content image in the bottom left corner of the layer.
  kCAGravityBottom
    Positions the content image centered along the bottom edge of the layer. 
  kCAGravityBottomRight
    Positions the content image in the top right corner of the layer.
 
  “图层的坐标系”标识了所支持的内容位置和他们相应的常量。
  图 1  layer的contentsGravity属性的定位常量
     CoreAnimation编程指南(五)图层内容 - 米安格 - 米安格的博客
 
  通过设置contentsGravity属性为其他一个常量(如表2所示)。图层的内容图片可以被向上或者向下拉伸, 仅当使用其他任何一个调整大小的常量的时候,contentsCenter属性才会对内容图片起作用。
 
  表 2  Layer的 contentsGravity 属性的缩放常量
  kCAGravityResize
    Resize the content image to completely fill the layer bounds, potentially ignoring the natural aspect of the content. This is the default.
  kCAGravityResizeAspect
    Resize the content image to scale such that it is displayed as large as possible within the layer bounds, yet still retains its natural aspect.
  kCAGravityResizeAspectFill
    Resize the content image to scale such that it is displayed filling the layer bounds, yet retaining its natural aspect. This may cause the content to extend outside the layer bounds.

  “变换图层的几何”演示了如何使用调整大小的模式来调整一个正方形图像的大小让其适应图层的方形边界。
  图 2  Layer的 contentsGravity 属性的缩放常量
      CoreAnimation编程指南(五)图层内容 - 米安格 - 米安格的博客
 
  注意:使用任何常量kCAGravityResize、kCAGravityResizeAspect和kCAGravityResizeAspectFill和表1中的重心位置常量无关。图层的内容将会填充整个边界,所以使用这些常量无法改变图层内容的位置。

转自梦维:http://www.dreamingwish.com/dream-2012/coreanimation-programming-guide-e-the-content-layer.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/500107.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

SHA算法

回顾散列算法 我的上篇文章:学习散列表 在上篇文章杂货铺的示例中,我们希望散列函数的结果是均匀分布的。散列函数接受一个字符串,并返回一 个索引号。 安全散列算法(secure hash algorithm, SHA)函数 给…

CoreAnimation编程指南(六)动画

动画是当今用户界面的关键因素。当使用核心动画的时候,动画是自动完成的。没有动画的循环和计数器。你的应用程序不负负责重绘,也不负责跟踪动画的当前状态。动画在独立线程里面自动执行,没有和你的应用程序交互。本章提供了对动画类的概览&a…

CoreAnimation编程指南(七)图层Action

图层的行为在以下情况发生的时候被触发:从图层树里面插入或者删除一个图层,图层的属性值被修改了,或者程序显式要求。通常情况下,行为触发器是动画显示的结果所在。1.1 行为对象的角色一个行为对象是一个通过CAAction协议响应行为…

python实现搜索之二分查找

搜索 搜索是在一个项目集合中找到一个特定项目的算法过程。搜索通常的答案是真的或假的,因为该项目是否存在。 搜索的几种常见方法:顺序查找、二分法查找、二叉树查找、哈希查找 二分法查找 二分查找又称折半查找,优点是比较次数少&#x…

CoreAnimation编程指南(八)事务

图层的每个改变都是事务的一部分。CATransaction是核心动画类,它负责成批的把多个图层树的修改作为一个原子更新到渲染树。本章介绍了核心动画支持的两种事务。隐式事务和显式事务。1.1 隐式事务当图层树被没有获得事务的线程修改的时候将会自动创建隐式事务&#x…

写SQL语句需要注意的点

先回忆一下DDL和DML 创建表DDL create table t_xx(id int auto_increment primary key, name char(10),...) create table t_student( id int auto_increment primary key , name char(10), 外键id int, foreign key(外键id) references 外表t_class(外表id字段名) );插入数…

CoreAnimation编程指南(九)图层布局

NSView提供了经典的“stuts and springs”模式,用于视图调整大小的时候把关联到它父图层的视图重新调整位置。图层支持该模式,而且Mac OS X上面的核心动画提供了一个更通用的布局管理器机制,允许开发者自己写他们自己的布局管理器。可以为图层…

数据库优化、数据库基础等常用知识点总结

建表优化 1)数据库范式 第一范式(1NF):强调的是列的原子性,即列不能够再分成其他几列。 如电话列可进行拆分—家庭电话、公司电话第二范式(2NF):首先是 1NF,另外包含两…

CoreAnimation编程指南(十)KVC

CAAnimation和CALayer类扩展了NSKeyValueCoding协议,给键添加默认值,扩展了封装协议,支持CGPoint、CGRect、CGSize和CATransform3D关键路径。1.1 键-值编码兼容的容器类CALayer和CAAnimation都是键-值编码兼容的容器类,允许你修改…

CoreImage使用介绍

一、概述CoreImage.framework从iOS5开始启用,它使我们很容易就能处理图片的各种效果,色彩,曝光,饱和度,变形等等。不仅功能强大,而且可以直接使用GPU,效率很高,甚至可以实时的对视频…

一片文章概括大部分python面试基础常考题(部分有详解)

本片文章部分参考地址:https://segmentfault.com/a/1190000018737045 python是动态解释性的强类型定义语言 强类型:不允许不同类型相加。例如:整形字符串会报类型错误。 动态:不使用显示数据类型声明,且确定一个变量…

AssetsLibrary使用介绍

一、概述AssetsLibrary框架:从iOS4.0开始提供,可以通过它获取设备里的图片和视频等资料,以API的方式提供,而且界面式的,比UIImagePickerViewController灵活很多。既可以读又可以写。二、读取资料库中的全部资料1.大概步…

Objective-C成员变量声明方式探究

一、interface和 property 方式声明变量的区别1.你可以单独在interface中定义变量,而不用property定义;也可以只用property去定义,而不在interface中定义,当然用了property去定义,一般要在.m文件中用synthsize去合成相…

web处理高并发措施

高并发处理的思路,从几个方面进行解决 先来了解几个名词 QPS: 每秒处理的请求数量! 响应时间: 处理一个请求需要的时间! 吞吐量: 单位时间内的处理请求数量! 最大并发数: 同一时间能支持的最大请求数! 1、流量处…

经典逻辑编程题(本文用python实现)

在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。 思…

@interface使用详解

1.interface可以实现三种功能&#xff1a;(1)声明类:Class(2)声明类别:Category(3)声明扩展:Extension2.声明类&#xff1a;这个就比较常用了&#xff0c;在这里不多说。代码&#xff1a;interface SomeClass : NSObject <SomeDelegate>{}end3.声明类别&#xff1a;(1)类…

同一账号多处登录问题

思路 用户每次登录时生存一个随机字符串保存在服务器和客户端&#xff0c;用户每次访问验证这个字符串&#xff0c;不通过时则要求用户下线&#xff0c; 如果有两个用户先后分别登录同一个帐号&#xff0c;则后登录的那位产生的字符串必然会覆盖先登录的那位&#xff0c; 然后…

iOS中HTTP请求使用cookie

一、iOS中Http请求对cookie的默认处理&#xff1a;1.一直以为ios的http请求不会自动处理请求中的cookie&#xff0c;所以一直认为客户端请求默认是没有Session的&#xff0c;现在发现自己的想法错了很久。2.NSURLRequest默认的处理过程&#xff1a;类似于服务器端和网页端的ses…

python基础题

import functools from decimal import Decimal 字符串反转 import timea hello b functools.reduce(lambda x,y:yx,a) print(b) print(type(b))c .join(list(a)[::-1]) print(c)查找字符串 str_1我爱你中国 char_1中国 nPosstr_1.index(char_1) print(nPos)数组合并去重排…

[Cordova]JS和Native交互实现关键代码(iOS)

一、JS中定义的exec函数&#xff1a;define("cordova/exec", function(require, exports, module) 。关键实现代码如下&#xff1a;1.建立command对象&#xff0c;并且将命令推入commandQueuevar command [callbackId, service, action, actionArgs];commandQueue.p…