在平铺(UIViews)上绘制一个非常大的可缩放,可平移的内容:iOS

时间:2014-05-05 21:49:14

标签: ios uiview drawrect

在瓷砖上绘制大型可缩放内容(UIViews)的最佳方法是什么?我无法使用CATiledLayer因为会有部分内容仅在某个缩放级别后放大时可见(如地图中)。我正在绘制的内容是一个大图(条形图,线条等),它将根据提供的图形数据动态渲染。

来自Apple的文档here
 看起来你应该使用平铺并避免创建非常大的视图。我正在使用这种方法来平铺非常好的视图:Tiling
现在困难的部分是确定哪些内容通过特定的图块(例如,在 r-th 行和 c-th 列中的tile(r,c))。我尝试过的一个解决方案是为每个图块绘制整个内容并根据图块的位置对其进行转换,但随着用户滚动,这种情况变得非常缓慢和抖动。

使用上述方法确定特定磁贴内容的更快方法是什么? (这与Apple如何为CATiledLayer提供内容有关) OR
 有什么替代方法我可以考虑解决上述问题吗?

1 个答案:

答案 0 :(得分:0)

我已在Mac应用中完成此操作,其中视图的内容可能不适合RAM。

首先,您肯定想使用UIScrollView。滚动正确非常复杂,除非您准备编写十万行代码,否则不要自己尝试滚动。

在滚动视图中嵌入UIView子类,并监视滚动视图以查看可见区域(和缩放级别)的更改。

每当可见区域发生变化时,相应地从视图中添加/删除CALayer对象。

复杂的是你在用户滚动时无法更新图层,它会太慢。所以等待用户停止滚动,然后更新图层。并且在可见范围之外的区域中可以看到足够的图层,因此用户不会注意到。

以下是我处理延迟更新的方法:

- (void)userDidScroll
{
  // wait until the user has stopped scrolling, then process scroll
  static NSDate *lastScrollDate = nil;
  lastScrollDate = [NSDate date];
  NSDate *thisScrollDate = lastScrollDate.copy;

  double delayInSeconds = 1.0; // how long after the scroll should we update?
  dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC));
  dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
    if (thisScrollDate != lastScrollDate)
      return;
    lastScrollDate = nil;

    [self updateLayer];
  });
}