在放大iPad 3rd gen时,CATiledLayer被删除并刷新

时间:2012-05-03 13:43:18

标签: objective-c ios ipad pdf catiledlayer

当父UIScrollView放大时,我在CATiledLayer上遇到重绘问题。

我在CATiledLayer支持的UIView中呈现PDF页面。它后面还有另一个UIImageView,它包含了CATiledLayer将绘制的页面的低分辨率图像。当我放大时,它按预期工作。 CATiledLayer将根据缩放级别渲染更高分辨率的图像。

缩放后出现问题。如果我放大然后只留下iPad,显示的图像会模糊然后重新加强。看起来CATiledLayer正在被删除,因为我在后备视图中看到模糊的低分辨率图像,然后重新绘制了CATiledLayer,即我看到了平铺效果和图像的重新锐化。如果我只是单独离开应用程序并等待大约30到40秒,就会发生这种情况。我只是在iPad第三代(新iPad,iPad3等)上观察过它。我也在测试iPad2,我还没有遇到这个问题。

还有其他人遇到过这个问题吗?任何已知的原因,可能还有解决方案?

编辑:

我的UIScrollViewDelegate方法如下:

// currentPage, previousPage, and nextPage are the pdf page views
// that are having the refresh problem 

- (void)positionBufferedPages { 
  // performs math {code omitted}

  // then sets the center of the views
  [previousPage.view setCenter:...];        
  [nextPage.view setCenter:...];
}

- (void)hideBufferedPages {
  if ([previousPage.view isDescendantOfView:scrollView]) {
    [previousPage.view removeFromSuperview];
  }

  if ([nextPage.view isDescendantOfView:scrollView]) {
    [nextPage.view removeFromSuperview];
  }          
}

- (void)showBufferedPages {
  if (![previousPage.view isDescendantOfView:scrollView]) {
    [scrollView addSubview:previousPage.view];
  }

  if (![nextPage.view isDescendantOfView:scrollView]) {
    [scrollView addSubview:nextPage.view];
  }

  if (![currentPage.view isDescendantOfView:scrollView]) {
    [scrollView addSubview:currentPage.view];
  }
} 

- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView {
  return currentPage.view;
}

- (void)scrollViewWillBeginZooming:(UIScrollView *)scrollView withView:(UIView *)view {
  [self hideBufferedPages];
}

- (void)scrollViewDidEndZooming:(UIScrollView *)scrollViewParam withView:(UIView *)view atScale:(float)scale {
  [self positionBufferedPages];
  [self showBufferedPages];    
}

- (void)scrollViewDidZoom:(UIScrollView *)scrollView {
  // nothing relating to the pdf page view
  // but does set the center of some other subviews on top of the pdf page views
}

不确定这会有多大帮助,因为当问题发生时,scrollview没有收到输入。如上所述,pdf页面被加载到CATiledLayer,然后我独自离开iPad(设备没有收到任何输入),CATiledLayer将自行重绘。

我还尝试在视图和平铺图层上捕获对setNeedsDisplaysetNeedsDisplayInRect:setNeedsLayoutsetNeedsDisplayOnBoundsChange:的调用,但重绘时没有任何调用被调用的那些函数当然,drawLayer:inContext:被调用,但跟踪只显示在后台线程中启动的一些Quartz调用(正如预期的那样,因为平铺层在后台准备内容),所以它也无济于事。

提前致谢!

4 个答案:

答案 0 :(得分:1)

我遇到了完全相同的问题。在我的情况下,它是由使用UIGraphicsBeginImageContext()函数引起的;此功能没有考虑到比例,这给视网膜显示器带来了问题。解决方案是用UIGraphicsBeginImageContextWithOptions()替换调用,并将scale(= third)参数设置为0.0。

如果您将代码基于Apple的Zooming PDF Viewer示例代码,就像我一样,那么这也可能解决您的问题。

答案 1 :(得分:1)

你的应用程序的内存使用情况如何?如果发生内存警告,CATiledLayer将丢弃其缓存并重绘。即使没有将内存警告发送到应用程序(只是比平时更高的内存负载),我已经看到它这样做了。使用Instruments查看内存使用情况。您可能需要使用OpenGL ES Driver仪器来查看图形内存的运行情况。

答案 2 :(得分:1)

Longshot,你是否有机会在非主线程上调用任何方法?如果你这样做,会发生各种意想不到的时髦事情。

答案 3 :(得分:1)

我和一位苹果工程师讨论了这个问题,简短的回答是iOS只有X内存可用于缓存CATiledLayer,而在iPad的Retina显示屏上,只有太多的像素可以使用多个图层

我一直在使用两个CATileLayers来显示顶部的地图视图和绘图视图。我删除了第二个CATiledLayer,问题就消失了。