带有大型CATiledLayer的UIScrollView +渲染速度快的Overlay

我一直在努力工作几个星期(iOS),我似乎无法找出一个可以接受的解决scheme。

要求

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

把它想象成一个虚构的小镇的地理地图,在上面绘制一个疯狂的道路,线路,区域和build筑系统。 CGPaths与各种不透明的填充,一些图标图像等混合物。这就像一个更复杂的谷歌地图应用程序的版本。

我试过了:


1 – 多个CATiled图层

查看层次结构:

  • 滚动型
  • – > ContainerView
  • – > TiledView(CATiledLayer 10000×10000)
  • —> OverlayView(CATiledLayer 10000×10000)

结果:从魔法苹果caching中左右丢弃瓦片。 两个CATiledlayers似乎不是正确的道路。 更新重叠不是很快。


2 – 用于OverlayView的子类TiledView

查看层次结构:

  • 滚动型
  • – > OverlayView(TiledView CATiledLayer 10000×10000的子类)

结果:渲染覆盖的更新时间过长。 慢点更新瓷砖


3 – 滚动视图w /一个容器视图

查看层次结构:

  • 滚动型
  • – > ContainerView(10000×10000)
  • – > OverlayView(CALayer 10000×10000)
  • – > TiledView(CATiledLayer 10000×10000)

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


4 – 使用滚动委托和CTM比例/翻译来模拟大的OverlayView

查看层次结构:

  • OverlayView(CALayer 1024×768)
  • 滚动型
  • – > TiledView(CATiledLayer 10000×10000)

结果:我使用scrollview委托来调整覆盖视图的偏移和缩放。 这个方法的问题是,drawrect被称为每秒100次,overlay视图不能足够快,所以它完全落后到1fps。


那就是我所在的地方。 我觉得这最后一种方法是有用的,但是需要一些疯狂的工作来驯服疯狂的疯狂。 其他的想法是试图解决OpenGL中的东西。

在我开始做这些事之前,我曾想过要求社区看看他们会做些什么,或者做些什么来面对类似的要求。

谢谢你的帮助。

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

所以你在你的customView中没有任何东西,并确保滚动等是你想要的。 如果问题出现在背景视图中,则需要解决该问题。

在这一点上,你的自定义视图开始绘制的东西。 请注意,您将得到一个rect在drawRect中更新。 也许你有一千个项目可能需要在整个canvas上画 – 所以每个都有一个框架属性,所以你可以确定给定的当前缩放和框架需要绘制。 你只画这些项目。

这个通用技术在过去对我来说工作得很好。

EDIT2:

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

然后你会确保你得到scrollView消息“scrollViewDidScroll:”,可能还有其他的。

当scrollView是稳定的,或者你et上面的消息,那么自定义的UIView子类会得到一个消息,说绘制,但使用scrollView contentOffset的偏移量。

自定义类必须做的工作是一样的。 而不是使用它的drawRect原点,它取得了这一点,并通过scrollView的contentOffset偏移它。 现在,当您绘制时,您正在通过滚动视图偏移正面查找在drawRect:rect偏移量中传递的点范围内的对象。

我绘制了一个基于path的地图,但是我没有背景图片,只有path。 我只用了一个View(没有滚动视图),自己实现了滚动/缩放。 那里有一些性能问题,特别是在高分辨率的ipad3,因为它有分配全分辨率imagecontext的问题。

  • 不要在path上使用阴影等,这会杀死你的performance。
  • 预先计算path/对象的所有边界框,并按照某种顺序存储它们,以便尽可能快地查找可见path/对象。
  • 为不同的缩放级别使用不同的详细path。

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

老问题,但每个人都在为此苦苦挣扎。 您应该使用两个以相同方式放大/滚动的“平铺视图”,但叠加视图不应该是背景视图的子视图。 那就是,你应该有:

  • 滚动型
  • – > ContainerView
  • – > TiledView(CATiledLayer 10000×10000)
  • – > OverlayView(CATiledLayer 10000×10000)

然后,为了绘制速度,这实际上取决于你如何绘制覆盖图。 对于每个图块,您应该确保只绘制覆盖图块的图块,而不是所有其他的图块边界之外的东西。