熊猫麻将手机版1.0.3 当前位置:首页>熊猫麻将手机版1.0.3>正文

熊猫麻将手机版1.0.3

发布时间:2018-12-10

原标题:Core Animation 文档翻译(第三篇)

“此剑虽然曾是我的先人所用,却显然与我无缘,”赵芜女低声道,“那风、调、雨、顺四位天王马上就是攻打进来,我们如果死在这里,此剑也难免会被他们发现。龙神应龙原是我的外祖父,他本就是为了对抗天庭而死,无论如何,我也不愿意东海秀霸剑就这样落到西王母手中。若是风公子有能力将它收服,我便将它赠给公子。”

吉祥棋牌苹果

“也不是每一个世界的位面意志,或者说是天道都有很强大的修正能力,有的天道是随意发展,篡改了也不会去修正路线,而是任由其继续发展下去,而有的却是千方百计的以天地规则进行干预尽可能的让大致的路线回归到原来的设定当中。”
现在她所修炼的玄阴星辰诀才完成了第一个元神的凝练,那就是对应真元的凝练,星力和玄阴杀气还没完,所以刘皓才要她最近以这方面的修炼为主,他同样也是如此。

弗兰德道:“那银斗魂队伍也行。你没看到,他们中只有一名刚刚达到金斗魂称号的魂师么?”

Core Animation 文档翻译(第三篇) 

 


 

 设置Layer对象

 

当我们使用核心动画时,Layer对象是一切的核心。Layers 管理我们APP的可视化content,Layer也提供了content样式及content可视化的外观的调整选项。尽管iOSAPP自动支持Layer,但是OS XAPP必须明确开启Layer的使用才能利用这些相关的性能特点。一旦开启Layer的使用,我们需要去理解如何配置和操作Layers才能得到想要的效果。

 

为APP开启核心动画的支持

 

在iOS APP里,核心动画是一直支持的并且每个view 都关联一个Layer(这种view被称为layer-backed view)。在OSX APP中,必须手动开启核心动画的支持,关联QuartzCore framework。(iOS APP必须关联这个framework仅当使用核心动画接口时候)。

开启Layer的支持后,创建layer-backed view是其功能之一,这种View,系统将会负责为其创建Layer对象并保持那个Layer的更新。

 

 调整和View关联的Layer

 

Layer-backed view 默认创建一个CALayer类的实例,大多数情况下我们不需要其他样式的Layer对象。然而,核心动画提供了其他的Layer类,各个Layer类都具有特殊的功能。选择对应的Layer类有助于我们提高性能,或者有助于以一种更简单的方式显示特殊样式的content。例如CATiledLayer类为高效的展示大图而优化设计的。

 

 改变Uiview的Layer类

 

我们能够改变iOS View 的Layer类别通过重写layerClass方式并一个不同的类。许多iOS Views创建一个CALayer对象并使用该对象作为content的存储。对于许多我们自己的Views,默认的layer类别就是一个不错的选择。但是在某些特定的场景别的Layer类是更合适的。例如,我们可能想要去改变Layer类在一下场景:

  ·我们的View绘制content通过使用Metal 或者OpenGL ES,此时我们需要使用CAMetalLayer 或者CAEAGLLayer 对象。

  ·当有特定的Layer类提供更好的性能。

  ·我们想要利用某些特定的核心动画Layer类别。例如粒子发射或者粒子复制

改变View的Layer类的方式是很简明的;就像2-1所示一样,我们需要做的只是重写LayerClass方法并且返回我们想要使用的类对象在展示之前View将会先调用layerClass方法,并使用它返回的类对象创建一个Layer对象,一旦创建后,该view的layer对象讲不可更换。

+ (Class) layerClass {
   return [CAMetalLayer class];
}

相应的Layer类别的列表,和如何使用它们,参见 Different Layer Classes Provide Specialized Behaviors。

 

 各种Layer类提供对应的特性

 

核心动画定义了许多标准的Layer类,每一个都具有特定的用途。CALayer是根类,它定义的特性其他所有的Layer都必须支持,CALayer也是默认的类别。当然,我们也可以使用2-1表中的Layer类。

 

Table 2-1  CALayer subclasses and their uses

 

Class

Usage

CAEmitterLayer

实现核心动画中粒子发射系统,发射器Layer控制粒子的生成和他们的原点。

CAGradientLayer

用来画颜色的渐变,以便于用渐变的颜色填充layer上面的形状(一般指绘制的图形)。

CAMetalLayer

用于设置和渲染可绘制的纹理(用于渲染layer 的content通过使用Metal)

CAEAGLLayer/CAOpenGLLayer

用于设置后端存储和渲染layer 的content的上下文(OpenGL ES或者OpenGL )

CAReplicatorLayer

当想要自动拷贝一个或多个子layer时,复制器创建副本,并使用我们指定的属性改变外观或者副本的属性。

CAScrollLayer

用于管理一个由许多子layer复合而成的可滚动的区域。

CAShapeLayer

用于画一个三维或者二位的贝塞尔曲线。这种layer在绘制基于path形状方面是有利的,因为他们总会创建出一个完善的path;而我们将path绘制到某个layer的后台存储的,看起来将会有瑕疵当缩放的时候。然而,这个完善的性能牵涉到在主线程渲染该形状并缓存这个结果。(个人觉得他应该是保存的矢量图)

CATextLayer

用于渲染文本中普通的或者属性字符串。

CATiledLayer

用于管理能够被分割成许多小块并单独渲染的大图,并支持缩小和放大content.

CATransformLayer

用于渲染真实的3D layer 图层(而不是其他layer类别所展现的平面图层)

QCCompositionLayer

用于渲染一个Quartz Composer 合成品 (OS X only)。

 

 为Layer提供contents

 

Layers是管理(由APP提供)content的数据对象。一个Layer的content由包含要被展现的可视化数据的bitmap所组成。我们可以通过以下三种方式提供bitmap:

  ·直接将一个image对象关联到Layer对象的content属性上。(对于很少或者不会改变的Layer content而言,这是最好的方式。)

  ·为Layer关联一个代理并让这个代理绘制Layer的content。(对于可能定期或者偶尔改变的Layer content,或者要通过某个对象提供contnent,例如view,这是最好的方式。)

  ·定义一个Layer的子类并且重写他的绘制方法以便提供Layer的contents。(如果我们不得不创建一个Layer的子类,或者如果我们想要去改变Layer基础的绘制行为,这将是最合适的方法。)

 

当我们单独创建Layer对象时,也是唯一我们需要考虑怎么为Layer提供content的时候,如果我们的APP只包含layer-backed view,我们不必考虑前面提到的如何提供Layer content的方法。Layer-backed views将会尽可能的以最有效的方式为他们关联的Layer提供contents。

 

 将一个image作为Layer的content

 

因为一个Layer仅仅是一个管理bitmap image的容器,所以我们直接为Layer的contnent属性关联一个image。将一个图片关联到Layer是很便捷的,并且能让我们轻松的指定一个图片显示到屏幕上,Layer使用我们直接提供大的Image,并且将不会创建那个图片的副本。当我们的APP在多个地方使用同一个图片,这个方式可以节约内存。

我们关联到Layer的图片必须是一个CGImageRef类型。(在OSX v10.6和之后,我们也可以关联NSImage对象。)当关联某个图片的时候,记住要提供和设备的分辨率相匹配的图片。对于Retina屏幕的设备而言,我们需要调整图片的contentsScale属性,更多关于为Layer提供高分辨率contnet可以参见 Working with High-Resolution Images。

 

 通过代理为Layer提供content

 

如果我们的Layer需要动态改变,当需要改变的时候,我们可以使用代理对象来提供或者更新content,在显示的时候,Layer通过调用代理的方法来提供所需要的content。

  ·如果代理实现了displayLayer:方法,那么该方法的实现体需要为创建一个bitmap并将该bitmap关联到Layer的content属性中。

  ·如果代理实现了 drawLayer:inContext:方法,核心动画将会创建bitmap,以及创建用于绘制bitmap的图形context,并调用这个代理方法填充bitmap,此代理方法需要做的就是将所需内容绘制到图形context中。

 

代理对象必须实现displayLayer: 或者drawLayer:incontext:方法,如果代理同时实现了这两个方法,那么代理仅仅只会执行displayLayer:方法。

当我们的APP需要加载或者创建要显示的bitmap的时候,重写displayLayer:方法是最合适的方法。代码清单2-3展示了displayLayer:代理方法的简单实现过程,在这个例子中,代理对象使用一个协助对象来加载所需要的image。代理方法选择显示哪个image取决于它自身的状态变量,这个变量在例子中就是这得自定义的属性displayYesImage。

 

Listing 2-3  Setting the layer contents directly

- (void)displayLayer:(CALayer *)theLayer {
    // Check the value of some state property
    if (self.displayYesImage) {
        // Display the Yes image
        theLayer.contents = [someHelperObject loadStateYesImage];
    }
    else {
        // Display the No image
        theLayer.contents = [someHelperObject loadStateNoImage];
    }
}

 

如果我们没有预先渲染bitmap,或者也没有供创建bitmaps的协助对象,那我们需要通过drawLayer:incontext:方法实现动态绘制content。代码清单2-4展示了drawLayer:incontext:方法的实现。在这个例子中,代理使用设定的宽度和渲染颜色绘制了一个简单的曲线path。

 

Listing 2-4  Drawing the contents of a layer

- (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, 5);
    CGContextStrokePath(theContext);
 
    // Release the path
    CFRelease(thePath);
}

 

对于需要自定义content的layer-backed views而言,我们仍然需要充写view的方法来实现绘制。一个Layer-backed view将他的Layer的代理关联给他本身,并实现了所需的代理方法,而且我们也不需要手动改变这个配置,不过,我们需要实现这个layer-backed view的drawRect:方法来绘制我们的content。

 

 通过子类提供Layer 的content

 

如果我们需要实现一个自定义的Layer,我们可以重写Layer的绘制方法做各种各样的绘制。不同于Layer对象自身生成自定义的content,layer需要管理这个用于显示的content(这句话应该是指的是相对于指定image提供content的方式)。例如,CATiledLayer类管理一个大的image的原理是:通过讲image分隔成许多小的可以单独管理和绘制的片段,由于这个Layer有关于在何时需要渲染那一个片段的信息,他直接管理了整个绘制行为。

当自定义子类的时候,我们需要实现下面两种绘制content的方式之一:

  ·重写子类的display方法,并直接在该方法中设置contents属性。

  ·重写子类的drawInContext:方法并且使用他在该图形context中进行绘制。

选择重写那种方法取决于我们需要控制绘制过程的程度。display方法是对于更新Layer的content的完全控制,因此重写该方法将使我们完全控制绘制的过程。重写display方法也意味着我们需要创建CGImageRef并将其关联到content属性。如果我们仅仅想要绘制content(或者让我们的layer管理绘制操作),我们可以重写drawInContext:方法,并让Layer创建后备存储。

 

 对我们提供的content进行调整

 

当将一个image关联到Layer的content属性时候,Layer的contentGravity属性决定了那个图片将被如何调整为了适应当前的bounds。默认的如果一个图片是比当前的bounds更大或者更小的,Layer对象就会缩放这个图片以便适应可用的空间,如果Layerbounds的宽高比是不同于image的宽高比,这将会引起图片显示效果不完全,我们可以使用contentsGravity属性来确保content以最好的方式展现。

可供使用的contentsGravity类型被分为两大种:

  ·基于position的重力常量,使我们可以在无缩放的情况下,从bounds的某个边或者角铺展image。

  ·基于缩放的重力常量,使我们可以以某几种方式之一伸缩image,有些选项可以维持宽高比,有些将不维持image的原有宽高比。

图2-1展示了基于点的重力设置对image的影响。除了kCAGravityCenter常量的使用,其他的常量将会以image bounds的某个边或者角来铺展image。kCAGravityCenter常量将image从中心开始铺展。这类常量不会引起图片的伸缩,因此image会按照原来的尺寸进行渲染。如果image是大于Layer的bounds,这将会导致image一部分被裁减掉,如果image的尺寸是小于Layer的bounds,如果设置了layer的背景色,空缺的部分将会显示Layer的背景色。

 

Figure 2-1  Position-based gravity constants for layers

 

图2-2展示了基于缩放的重力常量如何影响image显示的。如果image的尺寸和Layer的bounds不一致,所有的这些常量将会缩放image。这些常量的不同之处在于如何调整这些图片原来的宽高比,其中有些模式是保持原来的宽高比,还有一些将会改变原来的宽高比。默认情况下Layer的contentsGravity属性是被设置为kCAGravityResize 常量,这是该类型中唯一不保持图片原有宽高比的图片。

 

  Figure 2-2  Scaling-based gravity constants for layers

 

 如何使用高分辨率的Images

 

Layers本身并不知道所在设备屏幕分辨率。Layer仅仅存储指向bitmap的指针并使用所给定的可利用的像素按照尽可能好的方式展现。如果我们将一个Image关联到一个Layer的content属性,我们必须通过设置Layer的contentScale属性告诉核心动画Image的分辨率。ContentScale属性的默认值是1.0,这只适用于那些将要显示到标准分辨率屏幕的Image,如果我们的Image想要显示到Retina屏幕上,那么我们就必须设置这个属性为2.0。

 

如果我们直接关联一个bitmap到Layer,那么我们就需要设置contentScale的属性。为了适配屏幕的分辨率和被View管理的content,UIKit 和AppKit框架中 layer-backed view会自动设置Layer的缩放因子。例如,在OSX中,如果我们关联一个NSImage对象到Layer的contnet属性,AppKit将会查找标准和更高分辨率的Image,如果都有,那么AppKit将会使用正确的分辨率的image来设置contentScal的属性

 

 调整Layer的可视化风格和展示样式

 

Layer对象可以创建可视化的配件来增添Layer的主要contents,例如边框和背景色。这些可视化的配件不需要我们自己做任何的渲染工作,因此在某些情况下就可以使用Layer作为单独的整体。所有需要我们做的仅仅是设置Layer的属性,Layer将会处理所需的绘制工作,当然也包含任何动画。对于可视化配件是如何影响Layer显示的说明可以参见 Layer Style Property Animations。

 

 Layer有他们自己的背景和边框

 

除了他的基于image的content之外,一个Layer可以显示填充的背景和填充的边框。背景色是在Layer的content后面渲染的,边框是在image的content的上面渲染的,就像图2-3所示。如果Layer包含子Layer,他们也出现在边框的下面。由于背景色是放置在image的后面的,image的透明的部分将会显示背景色。

 

Figure 2-3  Adding a border and background to a layer

 

 

 

代码清单2-5显示设置Layer的背景色和边框所需要的代码,所有这些属性都是可动画的。

myLayer.backgroundColor = [NSColor greenColor].CGColor;
myLayer.borderColor = [NSColor blackColor].CGColor;
myLayer.borderWidth = 3.0;

注意:我们可以使用任何颜色作为Layer的背景色,包括带有透明分量的颜色或者使用样品image。当使用样品image的时候,要注意Core Graphics 处理图片的渲染,以及在此处理图片渲染的过程中将使用标准坐标系统,标准坐标系统和iOS中默认的坐标系统是不同的。在iOS上默认情况下,图片渲染是上下颠倒的,除非我们调整坐标系统。

 

如果我们设置Layer的背景色为不透明的颜色,那么我们应该讲Layer的opaque属性设置为YES,这么做将会提升性能当合成该Layer到屏幕上显示时候,并消除了layer 作为辅助存储时候管理的透明通道。如果Layer有非0的圆角,我们就不必将该Layer标记为不透明。

 

 Layer支持圆角

 

通过添加corner radius,我们可以为Layer创建圆角效应。corner radius是一个可视化配件,它可以遮盖Layer的四角让下面的content显示出来。就像图2-4显示的。它涉及到透明遮罩的应用,corner radius不影响image的Layer中的content属性,除非设置masksToBounds属性为YES。然而,corner radiu 一直影响Layer的背景色和边框的绘制。

 

Figure 2-4  A corner radius on a layer

 

 

为了将corner radius应用到Layer,我们需要为Layer的cornerRadius属性指定一个值。圆角的指定单位是points,并且显示的时候,它将会预先应用到Layer的四个角。

 

 Layer支持内建阴影

 

CALayer 类包含几个为配置阴影效应的属性。阴影会通过让它看起来像是漂浮在content下面的方式来为Layer添加深度。这是另外一种可视化的配件,当APP需要的时候可以使用。对于Layer而言我们可以控制阴影的颜色,相对于content的位置,不透明度,和形状。

Layer阴影的不透明度默认被设置为0,这将会有效的隐藏阴影。改变一个透明度为非零的值,将会引起核心动画绘制阴影。阴影默认是被直接放置在Layer的下面的,为了能够看到阴影,我们也需要调整阴影的偏移量。有个很重要的事情需要记住,我们为阴影指定的偏移量是基于Layer的本地坐标系统的,也就是说在iOS和OSX 上面是不同的。如图2-5展示了一个偏向右下的阴影,在iOS中,需要指定一个正数在Y轴分量上,但是在OSX 上就需要指定为负值。

 

Figure 2-5  Applying a shadow to a layer

 

当为Layer添加阴影的时候,阴影就是Layer的content的一部分,但是实际上阴影有可能超出Layer的边界,如果开启Layer的maskToBounds属性那么阴影的效应将会在Layer的边界处被裁剪,这将会产生一个奇怪的现象,那就是在Layer的内部的阴影是显示的,但是在Layer的边界外部的阴影缺看不到。如果我们想要显示完整的阴影并且还想使用bounds masking,我们就应该使用两个Layer而不是一个,将mask应用到包含content的Layer上,然后将这个Layer嵌入到第二个Layer上,第二个Layer的尺寸和第一个的尺寸一样,第二个Layer上设定阴影效果。

更多关于如何Layer上如使用阴影可参见Shadow Properties。

 

 为Layer添加自定义属性

 

CAAnimation 和CALayer 类延伸了KVC以便支持自定义属性。我们可以其使用这个特性为Layer添加数据,然后通过自定义的属性获取该数据。我们甚至可以关联actions到自定义的属性中,进而达到当修改这个属性的时候,对应的动画将会被执行。

为更多的信息关于如何使用和设置自定义属性,可以参见 Key-Value Coding Compliant Container Classes。为更多的信息关于添加actions到Layer对象,可以参见 Changing a Layer’s Default Behavior。

 

 打印Layer-backed View的内容

 

在打印期间,Layer 会重绘他们的contents为了适配打印环境。核心动画正常情况下依靠缓存的bitmap当渲染到屏幕上的时候,然而他将会重绘制content当打印的时候。尤其,layer-backed view使用drawRect:方法提供Layer 的content,当打印的时候,核心动画将再次调用drawRect:来生成需要打印的Layer的content。

 

编辑:秉乙

发布时间:2018-12-10 02:07:41

当前文章:http://www.radiokey.biz/ask/18-11-1294670.html

集结号游戏版官方下载 集结号游戏中心客服 建德手游棋牌 三公扑克牌出千技巧 送30元现金棋牌 弈棋耍大牌游戏下载 众博棋牌官网电脑版 众发棋牌骗局

93388 57109 47329 66685 58238 7331787456 23957 27406

责任编辑:杜建文海

随机推荐