简体   繁体   English

CALayer带来麻烦

[英]Drawing woes with CALayer

First of all, im finding the iPhone online docs to be not-so-very thoroughly clear when it comes to the various ways of rendering a layer. 首先,就各种渲染层的方式而言,我发现iPhone在线文档不太清楚。 I get the jist of it, but im not clear when to use which methods and which requires the layer to be added as a sub layer or not. 我明白了,但是我不清楚何时使用哪种方法以及哪种方法需要将该层添加为子层。

My project started off trivially with me loading images and simply drawing them to a UIView via [image drawAtPoint:] as well as [image drawInRect:]. 我的项目很简单,首先是加载图像,然后通过[image drawAtPoint:]和[image drawInRect:]将它们绘制到UIView中。 These work fine using the current graphics context. 使用当前的图形上下文,它们可以正常工作。

Then today i happened to read this concept of using layers so that animating my various images (implicitly) would in theory be a breeze! 然后,今天我碰巧阅读了使用图层的概念,因此从理论上讲,使我的各种图像(隐式地)动画化是一件轻而易举的事!

For the record, i know the docs say subclassing CALayer is unecessary, but i did just that. 作为记录,我知道文档说对CALayer进行子类化是不必要的,但我只是这样做了。 Now I am incredibly confused about the different ways to supposedly render a layer. 现在,我对于应该渲染图层的不同方法感到非常困惑。

  • drawLayer drawLayer
  • displayLayer displayLayer
  • display 显示
  • drawInContext drawInContext

Now for all of these methods, is it required to set the layer's frame size? 现在,对于所有这些方法,是否都需要设置图层的帧大小? Is it required to add a layer to a view's layer? 是否需要在视图的图层中添加图层?

The only method that gives me visible results is the drawinContext method. 给我可见结果的唯一方法是drawinContext方法。 But if i apply an implicit animation (eg image.opacity = 0) nothing happens, which makes me believe my layer is not properly set up. 但是,如果我应用隐式动画(例如image.opacity = 0),则什么都不会发生,这使我相信我的图层没有正确设置。

Some one please bring order back to this chaos. 请有人将命令带回这个混乱状态。

Core Animation does make this sort of thing trivial. Core Animation确实使这种事情变得微不足道。 Brad's suggestion is right on. 布拉德的建议是正确的。 The bottom line is that you don't need any of those methods to simply render the layer. 最重要的是,您不需要任何这些方法即可简单地渲染图层。 In order to cause the layer to render, make sure you've done the following: 为了使图层渲染,请确保已完成以下操作:

  • Set the contents property with: 使用以下命令设置contents属性:

    [imageLayer setContents:(id)[[UIImage imageNamed@"image.png"] CGImage]];

  • Set the bounds of the layer to the size you want. 将图层的边界设置为所需的大小。

    [imageLayer setBounds:CGRectMake(0.0f, 0.0f, 50.0f, 50.0f)];

  • Set the position (x,y location) of the layer to display in the view. 设置要在视图中显示的图层的位置(x,y位置)。 The default anchorPoint is the center of the layer. 默认的anchorPoint是图层的中心。 This code centers the layer in your view. 此代码在您的视图中将图层居中。

    [imageLayer setPosition:CGPointMake([view bounds].size.width/2, [view bounds].size.height/2)];

  • Add the layer to your view's layer: 将图层添加到视图的图层:

    [[[self view] layer] addSublayer:imageLayer];

Incidentally, if you prefer, you can set both bounds and position in one method by calling -setFrame:. 顺便说一句,如果愿意,可以通过调用-setFrame:在一个方法中设置边界和位置。 I prefer to use the two calls myself as it feels more readable to me, but that's up to your own preference. 我更喜欢自己使用这两个调用,因为这对我来说更具可读性,但这取决于您自己的偏好。 If you do not set the bounds and position or frame of the layer, however, the layer will not render. 但是,如果不设置图层的边界和位置或框架,则该图层将不会渲染。

If you would prefer, you can avoid using drawInContext by creating additional layers that draw paths, shapes (see CAShaperLayer), or additional images and add them as sublayers of your image layer or add them as sublayers of your parent layer and give them a zPosition that causes them to display in front of your image layer. 如果愿意,可以通过创建其他绘制路径,形状(请参见CAShaperLayer)或其他图像并将其添加为图像层的子层或将其添加为父层的子层并为其指定zPosition的图层来避免使用drawInContext使它们显示在图像层的前面。

Now, if you want to animate the opacity, you can use implicit animation by simply setting the layer property in the exact manner you described, eg [imageLayer setOpacity:0.0f]; 现在,如果要设置不透明度的动画,则可以通过简单地按照您描述的方式设置layer属性来使用隐式动画,例如[imageLayer setOpacity:0.0f]; This will fade the layer and all of it's child layers over 0.25 seconds. 这将使图层及其所有子图层在0.25秒内褪色。

Just some additional thoughts. 只是一些其他想法。

Best Regards. 最好的祝福。

If all that you want your various layers to do is display one image each, you shouldn't need to subclass them at all. 如果您希望各层所做的全部只是显示一张图像,则根本不需要对它们进行子类化。 You should just be able to set an image (in CGImageRef form) to the contents property of each layer. 您应该只能够将图像(以CGImageRef形式)设置为每一层的contents属性。 The layer will then handle the drawing of that image. 然后,图层将处理该图像的绘制。 You can obtain the Core Graphics image representation of a UIImage using its CGImage read-only property. 您可以使用其CGImage只读属性获取UIImage的核心图形图像表示形式。

You are correct, though, about -drawInContext: being the right place to put more custom drawing code within a CALayer subclass. 但是,关于-drawInContext: ,您是正确的-drawInContext:在CALayer子类中放置更多自定义绘图代码的正确位置。 Without subclassing CALayer, you can have a delegate change the layer's drawing behavior through the -drawLayer:inContext: delegate method. 如果不使用CALayer子类,则可以使委托通过-drawLayer:inContext:委托方法来更改图层的绘制行为。

This is all described in detail within the "Providing Layer Content" section of Apple's Core Animation Programming Guide . 在Apple的《 核心动画编程指南 “提供图层内容”部分中对此进行了详细说明。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM