UIScrollView w / Large CATiledLayer + Overlay渲染速度快

时间:2012-08-27 22:43:47

标签: ios uiscrollview catiledlayer

我已经做了几个星期的事情(iOS),我似乎无法找到一个可接受的解决方案。

要求

  • 显示10000x10000像素的背景图片
  • 缩放和滚动响应
  • 在顶部覆盖有自定义绘图
  • 叠加中的元素是交互式的(点击和突出显示元素等),可以打开或关闭片段。
  • iOS 4.0

把它想象成一个虚构小镇的地理地图,上面画着一系列疯狂的道路,线条,区域和建筑物。混合各种不透明度的CGPaths,一些图标图像等。它就像一个更复杂的谷歌地图应用程序版本。

我尝试了什么:


1 - 多个CATiled图层

查看层次结构:

  • 滚动型
  • - > ContainerView
  • - > TiledView(CATiledLayer 10000x10000)
  • ---> OverlayView(CATiledLayer 10000x10000)

结果: 从魔法苹果缓存中向左和向右拖放瓷砖。两个CATiledlayers似乎不是正确的道路。叠加的更新速度不快。


2 - OverlayView的子类TiledView

查看层次结构:

  • 滚动型
  • - > OverlayView(TiledView CATiledLayer 10000x10000的子类)

结果: 花费太长时间来渲染叠加层的更新。 缓慢更新瓷砖


3 - Scrollview w /单个容器视图

查看层次结构:

  • 滚动型
  • - > ContainerView(10000x10000)
  • - > OverlayView(CALayer 10000x10000)
  • - > TiledView(CATiledLayer 10000x10000)

结果: 无法工作,因为OverlayView消耗太多内存。 TileView很好,因为它由CATiledLayer支持


4 - 使用滚动委托和CTM缩放/翻译来模拟大型的OverlayView

查看层次结构:

  • OverlayView(CALayer 1024x768)
  • 滚动型
  • - > TiledView(CATiledLayer 10000x10000)

结果: 我使用scrollview委托来调整叠加视图的偏移和缩放。这种方法的问题在于,drawrect被调用为每秒100次,并且叠加视图无法绘制得足够快,因此它完全滞后于1fps。


这就是我所在的地方。我觉得这最后一种方法是针对某些事情的,但是需要一些疯狂的工作来驯服那些直截了当的疯狂。其他想法是试图解决OpenGL中的问题。

在我开始做这些之前,我想我会要求社区看看他们在面对类似要求时会做些什么。

感谢您的帮助。

3 个答案:

答案 0 :(得分:2)

我的建议是在您的滚动视图中有两个视图。背景CATiledLayer视图。第二个视图是位于背景视图上方的自定义UIView - 这是您进行自定义绘图的位置。自定义视图应该有一个drawRect:方法,现在什么都不做。

所以你在customView中没有任何东西试试这个,并确保滚动等是你想要的。如果问题出在后台视图中,您需要解决该问题。

此时,您的自定义视图开始绘制内容。请注意,您将在drawRect中获得更新的rect。也许你有一千件物品可能需要画在整个画布上 - 所以每个都有一个框架属性,所以你可以确定给定的当前缩放和框架需要绘制的内容。你只画那些东西。

这种一般技术过去对我来说运作良好。

EDIT2:

因此在设备上运行时,我复制了“无法分配”的消息。所以计划B.你可以做的是有一个容器视图,它有两个视图 - 滚动视图和一个新的UIView子类。 scrollView有巨大的怪物视图。子类视图的框架恰好是UIScrollView框架。

然后,您将确保获得scrollView消息“scrollViewDidScroll:”,可能还有其他消息。

当scrollView稳定,或者你输入上面的消息时,自定义UIView子类会收到一条消息,说明是绘制但是使用了一个offset,即scrollView contentOffset。

自定义类必须完成的工作是相同的。它不是使用drawRect原点,而是采用该点并通过scrollView的contentOffset对其进行偏移。现在,当你绘制时,你正在寻找在drawRect中传递的点范围内的对象:由offsetview偏移正向偏移。

答案 1 :(得分:1)

我画了一张基于路径的地图,但我没有背景图片,只有路径。我只使用了一个带有drawrect的视图(没有Scrollview)并且自己实现了滚动/缩放。有一些性能问题,特别是在高分辨率的ipad3上,因为它有分配全分辨率imagecontext的问题。

  • 不要在路径上使用阴影等,这会影响你的表现。
  • 预先计算路径/对象的所有边界框并按某种顺序存储它们,以便您可以尽快查找可见路径/对象。
  • 为不同的缩放级别使用不同的详细路径集。

但最后我认为openGL是更好的解决方案。

答案 2 :(得分:0)

老问题,但是每个人都在努力解决这个问题。您应该使用两个以相同方式缩放/滚动的平铺视图,但叠加视图不应该是背景视图的子视图。也就是说,你应该:

  • 滚动型
  • - > ContainerView
  • - > TiledView(CATiledLayer 10000x10000)
  • - > OverlayView(CATiledLayer 10000x10000)

然后,对于绘制速度,它实际上取决于您如何绘制叠加层。对于每个图块,您应该确保只绘制覆盖图块的图块,而不是绘制在图块边界之外的所有其他图块。