4

我已经工作了好几个星期了(iOS),但我似乎无法找到一个可以接受的解决方案。

要求

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

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

我试过的:


1 - 多个 CATiled 层

查看层次结构:

  • 滚动视图
  • ->容器视图
  • -->TiledView (CATiledLayer 10000x10000)
  • --->OverlayView (CATiledLayer 10000x10000)

结果:左右从魔术苹果缓存中掉落瓷砖。两个 CATiledlayers 似乎不是正确的路径。覆盖的更新并不快。


2 - OverlayView 的子类 TiledView

查看层次结构:

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

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


3 - 带有单个容器视图的滚动视图

查看层次结构:

  • 滚动视图
  • ->容器视图(10000x10000)
  • -->OverlayView (CALayer 10000x10000)
  • -->TiledView (CATiledLayer 10000x10000)

结果:无法正常工作,因为 OverlayView 占用了太多内存。TileView 很好,因为它由 CATiledLayer 支持


4 - 使用滚动委托和 CTM 缩放/平移来模拟大的 OverlayView

查看层次结构:

  • OverlayView (CALayer 1024x768)
  • 滚动视图
  • ->平铺视图(CATiledLayer 10000x10000)

结果:我使用滚动视图代表来调整覆盖视图的偏移和缩放。这种方法的问题在于,drawrect 每秒调用 100 次,而覆盖视图的绘制速度不够快,因此它完全滞后到 1fps。


这就是我所在的位置。我觉得这最后一种方法很重要,但需要一些疯狂的工作来驯服drawrect的疯狂。其他想法是尝试在 OpenGL 中解决一些问题。

在我开始做这些之前,我想我会问社区看看他们会做什么/已经做了什么面对类似的要求。

谢谢你的帮助。

4

3 回答 3

2

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

因此,您在 customView 中没有任何内容尝试此操作,并确保滚动等是您想要的。如果问题出在后台视图中并且您需要解决该问题。

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

这种通用技术过去对我来说效果很好。

编辑2:

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

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

当 scrollView 稳定时,或者您收到上述消息时,自定义 UIView 子类会收到一条消息,说明 draw 但使用的偏移量是 scrollView contentOffset。

自定义类要做的工作是一样的。它没有使用它的 drawRect 原点,而是使用该点并通过 scrollView 的 contentOffset 偏移它。现在,当您绘制时,您正在寻找在 drawRect:rect 中通过滚动视图偏移正偏移的点范围内的对象。

于 2012-08-27T23:24:21.363 回答
1

我画了一次基于路径的地图,但我没有背景图像,只有路径。我只使用了一个带有drawrect的视图(没有滚动视图)并自己实现了滚动/缩放。那里存在一些性能问题,尤其是在具有高分辨率的 ipad3 上,因为它在分配全分辨率图像上下文时存在问题。

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

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

于 2012-08-28T06:27:16.890 回答
0

老问题,但对于每个为此苦苦挣扎的人。您应该使用两个以相同方式缩放/滚动的平铺视图,但覆盖视图不应是背景视图的子视图。也就是说,你应该有:

  • 滚动视图
  • ->容器视图
  • -->TiledView (CATiledLayer 10000x10000)
  • -->OverlayView (CATiledLayer 10000x10000)

然后对于绘图速度,它真的归结为你如何为覆盖进行绘图。对于每个图块,您应该确保只绘制覆盖图块的内容,而不是所有其他落在图块边界之外的东西。

于 2017-08-15T16:24:37.183 回答