在另一个UIView中渲染UIView的预览

时间:2013-07-30 18:05:32

标签: iphone objective-c cocoa-touch uikit quartz-core

我有一个非常有趣的障碍需要克服。我试图在另一个单独的UIView中显示UIView的实况内容。

我想要完成的工作与Mac OS X中的Mission Control非常相似。在Mission Control中,中心有大型视图,显示桌面或应用程序。在此之上,可以重新组织小视图。这些小视图显示其相应应用的实时预览。预览是即时的,帧速率是准确的。最终,我试图以尽可能便宜的方式重现这种效果。

我尝试了很多可能的解决方案,显示here的解决方案就像我已经接近一样。它可以工作,但是每次更改都不会调用- (void)drawLayer:(CALayer *)layer inContext:(CGContextRef)ctx方法。我的解决方案是使用CADisplayLink调用[cloneView setNeedsDisplay],因此在每次屏幕刷新时调用它。它非常接近我的目标,但帧率非常低。我认为[CALayer renderInContext:]太慢了。

如果可以让两个CALayers渲染相同的源,那将是金色的。但是,我不知道如何处理这个问题。幸运的是,这只是一个概念应用程序而不是App Store,因此我可以使用私有API。我已经研究过IOSurface和Quartz上下文,但到目前为止我还没能解决这个难题。任何意见都将非常感谢!

1 个答案:

答案 0 :(得分:1)

iOS和OSX在最低级别实际上大致相同。 (但是,当你在堆栈中越来越高时,iOS实际上比OSX更先进,因为它更新并且有一个新的开始)

然而,在这种情况下,他们都使用相同的东西(我相信)。你会发现一些关于Mission Control的事情。它隔离了“窗口”而不是视图。在iOS上,每个UIWindow都有一个“.contentID”属性,CALayerHost可以使用它来使渲染服务器在它们中的2个之间共享渲染上下文(2个层)。

所以我的建议是让你的视图分开UIWindows并获得免费的本机镜像 - (ish)。 (根据我的经验,CALayerHost使用渲染服务器接管目标图层位置,因此如果CALayerHost和窗口都可见,则窗口将不再存在,只有图层主机将成为(在OSX上使用它们的方式)和iOS不是问题)。)

因此,如果您正在使用真正的镜像,2份副本,您将需要诉诸于您正在考虑的那种事情。

1选项是创建一个使用的UIView子类 https://github.com/yyfrankyy/iOS5.1-Framework-Headers/blob/master/UIKit.framework/UIView-Rendering.h#L12 这个UIView私有方法为目标视图获取IOSurface,然后每秒使用一次CADisplayLink获取并绘制表面。

可能有效的另一个选项(我不确定,因为我不知道你的设置或所需效果)可能只是使用CAReplicatorLayer,它使用相同的后备存储显示CALayer的镜像(非常快速和有效+公共稳定的API)。

抱歉,我无法给你一个固定的,“这是答案回复”,但希望我已经给你足够的想法和可能性开始。 我还提供了一些您可能会发现有用的内容的链接。

What's the magic behind CAReplicatorLayer?

http://aptogo.co.uk/2011/08/no-fuss-reflections/

http://iphonedevwiki.net/index.php/SBAppContextHostManager

http://iphonedevwiki.net/index.php/SBAppContextHostView

http://iphonedevwiki.net/index.php/CALayerHost

http://iky1e.tumblr.com/post/33109276151/recreating-remote-views-ios5

http://iky1e.tumblr.com/post/14886675036/current-projects-understanding-ios-app-rendering