CATiledLayer 到 CALayer

Posted

技术标签:

【中文标题】CATiledLayer 到 CALayer【英文标题】:CATiledLayer to CALayer 【发布时间】:2012-06-20 15:11:59 【问题描述】:

我有一个带有 CATiledLayer 支持的视图。我想从这个 CATiledLayer UIView 中获取可见图块并将其添加到另一个视图作为其 CALayer 支持,从而在另一个不使用 CATiledLayer 的 UIView 中重新创建可见图像。

我想这样做的原因是我将使用第二个 UIView 来掩盖更新支持 CATiledLayer 的 UIView 的效果 - 这当前会在重新加载所有图块时产生闪烁。

问题是,我不完全确定我会如何做到这一点。有什么想法吗?

【问题讨论】:

所以你想采取一个故意平铺视图并制作一个普通视图来隐藏平铺视图......?也许是一个疯狂的问题,但为什么一开始是平铺的? @PauldeLange - 当我的平铺视图重新加载时,它会在重新绘制平铺时“闪烁”。平铺视图下方将有一个 UIView,它将是上面图块的直接副本。然后,当重新加载瓷砖时,底部视图将在重新加载瓷砖时显示一秒钟,从而停止闪烁效果。据我所知,这是图形程序相当普遍的做法 - 使用图形缓冲区来消除渲染上述任何新内容的影响。 如果你可以比瓷砖更快地渲染背景视图,为什么你有瓷砖?影响 -> 顺便说一下效果。 @Gaz_Edge 我从未见过 CATiledLayer 有任何闪烁。当您在其上调用“setNeedsDisplay”时,它将保留旧图像,而您的“drawLayer:inContext:”将简单地在其上绘制。您可能希望显示更多关于您如何绘制的详细信息,以及您正在设置的 CATiledLayer 上的哪些属性。 @Gaz_Edge 是正确的。您必须在 CATiledLayer 的委托的 drawLayer:inContext: 中进行绘图。在我的情况下,它始终是视图控制器。 【参考方案1】:

CATiledLayer 是 CALayer 的子类,提供了一种方法 异步提供图层内容的切片,可能 缓存在多个详细级别。

你可以将图层中可见的东西渲染到一个CGContextRef中:

- (void)renderInContext:(CGContextRef)ctx

然后使用它通过设置它的委托和实现来更新你的其他层

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

这里显示的ss http://www.raywenderlich.com/2502/introduction-to-calayers-tutorial

但老实说,我不认为这是有效的。

【讨论】:

感谢您的回答。你说效率不高。您还有其他想法可以帮助解决我的闪烁问题吗? @Luis renderInContext 似乎不适用于CATiledLayer,就像CALayer 对我一样。瓷砖根本不渲染。有什么想法吗?【参考方案2】:

您真正的问题是闪烁。我在自定义 CALayer 支持的视图上遇到了类似的问题,这是解决方案的一部分: 创建您的 CALayer 的自定义子类并实现以下方法:

- (void) display 
    self.contents = nil;
    [super display];

这为我解决了一系列问题,但可能无法为您解决。您的替代方法可能是在更新时禁用事务: 来自CATransaction Class Reference

setDisableActions: 设置动作是否触发 在此事务组中进行的属性更改被禁止。

所以要使用这个:

[CATransaction begin];
[CATransaction setDisableActions:YES];
// do updating/flickering stuff
[self doFlickeringThing];
[CATransaction commit];

【讨论】:

以上是关于CATiledLayer 到 CALayer的主要内容,如果未能解决你的问题,请参考以下文章

CATiledLayer

在 CATiledLayer 中预加载/预显示图块?

如何从我的 CATiledLayer 中移除这些旋转伪影?

在 UIScrollView 中拍摄 CATiledLayer 支持的视图的图像快照

CATiledLayer:示例代码

CATiledLayer 的背景图像