在 iPhone 上(虽然我认为这在 Cocoa 中同样有效)我有一个 UIScrollView 围绕一个由 CATiledLayer 支持的 UIView。默认情况下,它的工作方式是在我的视口滚动到 CATiledLayer 的空白部分时加载任何未缓存/未获取的切片。
我想知道的是,是否有办法触发 CATiledLayer 加载未主动显示的图块?例如,我想在它们仍在屏幕外时预加载与当前显示的图块相邻的所有图块,从而避免在异步加载后闪烁的空白屏幕淡入图像。
有任何想法吗?
在 iPhone 上(虽然我认为这在 Cocoa 中同样有效)我有一个 UIScrollView 围绕一个由 CATiledLayer 支持的 UIView。默认情况下,它的工作方式是在我的视口滚动到 CATiledLayer 的空白部分时加载任何未缓存/未获取的切片。
我想知道的是,是否有办法触发 CATiledLayer 加载未主动显示的图块?例如,我想在它们仍在屏幕外时预加载与当前显示的图块相邻的所有图块,从而避免在异步加载后闪烁的空白屏幕淡入图像。
有任何想法吗?
我不认为 CATiledLayer 会做你想做的事。不过,还有其他几个选择。首先,您可以禁用磁贴淡入并立即显示,如下所示:
@interface NoFadeTiledLayer : CATiledLayer {
}
@end
@implementation NoFadeTiledLayer
+ (CFTimeInterval)fadeDuration {
return 0.0;
}
@end
@implementation MyViewWithTiledLayer
+ (Class)layerClass {
return [NoFadeTiledLayer class];
}
...
@end
其次,您可以自己预取和缓存相邻的图块,以便在 CATileLayer 调用 drawLayer:inContext 时准备好它们。我会实现scrollViewDidScroll:和scrollViewDidZoom:来确定相邻的图块和levelOfDetail。然后进行缓存查找并将任何不存在的内容添加到预取/渲染队列中。后台线程可以为队列提供服务,随后的滚动或缩放将清除并重建队列。然后让 drawLayer:inContext 首先检查缓存,并在必要时仅获取/渲染。
CATileLayer 是那些令人沮丧的类之一,它做了一件很棒的事情,但没有灵活性。
在这一点上,留给我们的只有创造力:
1)让你的滚动视图很大。在我不再看到“空白”图块之前,我尝试了 5 倍的屏幕大小。小心内存使用!即使用户只看到其中的 2%,您也正在绘制一个巨大的区域。
2)有两个版本的图像,一个高分辨率和一个低分辨率。您应该能够非常快速地对低分辨率进行 blit,并且基本上您会得到“模糊”而不是“空白”图块。Apple 的示例代码 ZoomingPDFViewer 向您展示了如何执行此操作。
http://developer.apple.com/library/ios/#samplecode/ZoomingPDFViewer/Introduction/Intro.html
当然,如果您想投入时间,两者的某种组合可能会起作用。
您应该尝试在要显示的区域上调用 setNeedsDisplayInRect:。如果您想保持在瓦片边界内,您可以使用 tileSize 属性来计算瓦片边界。
但我不确定这是否会起作用,我们也不知道切片缓存机制是如何工作的。