CATiledLayer转换为CALayer

9
我有一个使用CATiledLayer作为后备的视图。我想要从这个CATiledLayer UIView中获取可见的瓷砖,然后将其添加到另一个视图中作为它的CALayer后退,以此在另一个不使用CATiledLayer的UIView中重新创建可见的图像。
我想这么做是因为我将使用第二个UIView来遮蔽更新CATiledLayer后备UIView的效果——这目前会产生所有瓷砖重新加载的闪烁效果。
问题在于,我不完全确定如何做到这一点。你有什么想法吗?

1
所以你想采取有意瓷砖化的视图,并使普通视图隐藏瓷砖化的视图...?也许这是一个疯狂的问题,但为什么一开始要瓷砖化呢? - Paul de Lange
@PauldeLange - 当我的平铺视图重新加载时,它会出现“闪烁”,因为平铺被重新绘制。在平铺视图下方将有一个UIView,它将是上面平铺的直接副本。然后当平铺重新加载时,底部视图将在平铺重新加载时短暂地显示,从而停止闪烁效果。据我所知,这是图形程序的一种相当常见的做法-使用图形缓冲区来平滑渲染任何新内容的影响。 - GWed
1
@Gaz_Edge 我从未见过CATiledLayer出现任何闪烁。当您在其上调用“setNeedsDisplay”时,它将保留旧图像,并且您的“drawLayer:inContext:”将简单地在其上绘制。您可能希望展示一些有关您正在绘制的详细信息以及您正在设置的CATiledLayer属性。 - fishinear
@fishinear 你说的很有道理,这也是我认为平铺应该运作的方式,即没有闪烁。实际上我正在drawRect中实现绘图代码,这可能是我的问题所在。我会尝试使用drawLayer方法来替代它。 - GWed
1
@Gaz_Edge 没错。你必须在CATiledLayer的委托的drawLayer:inContext:方法中进行绘制。在我的情况下,这总是视图控制器。 - fishinear
显示剩余2条评论
2个回答

3
CATiledLayer是CALayer的子类,提供了一种异步提供图层内容瓦片的方式,可以在多个细节级别上进行缓存。
您可以使用以下代码将图层中可见的内容呈现到CGContextRef中:
- (void)renderInContext:(CGContextRef)ctx

然后通过设置其代理并实现相关功能,使用此方法来更新您的另一层。
- (void)drawLayer:(CALayer *)layer inContext:(CGContextRef)context 

如此展示:http://www.raywenderlich.com/2502/introduction-to-calayers-tutorial

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


谢谢你的回答。你说这不够高效。你有其他的想法可以帮助解决我的闪烁问题吗? - GWed
@Luis renderInContextCATiledLayer 上似乎不像在 CALayer 上对我那样有效。瓦片根本没有渲染。有什么想法吗? - Tim

0
你真正的问题在于闪烁。我曾经在一个带有自定义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];

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接