在 CATiledLayer 中预加载/预显示图块?
在 iPhone 上(尽管我认为这在 Cocoa 中也是一个同样有效的问题),我在由 CATiledLayer 支持的 UIView 周围有一个 UIScrollView。 默认情况下,它的工作方式是当我的视口滚动到 CATiledLayer 的空白部分时加载任何未缓存/未获取的图块。
我想知道是否有办法触发 CATiledLayer 加载未主动显示的图块? 例如,我想在当前显示的图块仍处于屏幕外时预加载与当前显示的图块相邻的所有图块,从而避免闪烁空白屏幕,一旦异步加载,该空白屏幕就会淡入图像。
有任何想法吗?
On the iPhone (though I imagine it's an equally valid question in Cocoa) I have a UIScrollView around a UIView backed by a CATiledLayer. The way it works by default is to load any uncached/unfetched tiles when my viewport scrolls over a blank section of the CATiledLayer.
What I would like to know is if there's a way to trigger CATiledLayer to load a tile that's not actively being displayed? I would like to, for example, preload all tiles contiguous to the currently displayed tile while they are still offscreen, thus avoiding flashing a blank screen that fades in to the image once it's loaded asynchronously.
Any ideas?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我不认为 CATiledLayer 会做你想做的事。 不过还有其他一些选择。 首先,您可以禁用图块淡入并立即显示,如下所示:
其次,您可以对相邻图块进行自己的预取和缓存,以便它们在 CATileLayer 调用 drawLayer:inContext 时准备就绪。 我将实现scrollViewDidScroll:和scrollViewDidZoom:来确定相邻的图块和levelOfDetail。 然后进行缓存查找并将任何不存在的内容添加到预取/渲染队列中。 后台线程可以为队列提供服务,随后的滚动或缩放将清除并重建队列。 然后让drawLayer:inContext 首先检查缓存,并且仅在必要时获取/渲染。
I don't think CATiledLayer will do what you want. There are a couple of other options though. First you can disable the tile fade-in and have it display immediately with something like this:
Second, you can do your own pre-fetch and caching of the adjacent tiles so they're ready to go when CATileLayer calls drawLayer:inContext. I'd implement scrollViewDidScroll: and scrollViewDidZoom: to determine the adjacent tiles and levelOfDetail. Then do a cache lookup and add any not present to a pre-fetch/render queue. A background thread could service the queue and subsequent scrolls or zooms would clear and rebuild the queue. Then have drawLayer:inContext check the cache first and only fetch/render if necessary.
CATileLayer 是那些令人沮丧的类之一,它做了一件很棒的事情,但缺乏灵活性。
此时,我们剩下的就是创造力:
1)让你的滚动视图变大。 在我不再看到“空白”图块之前,我尝试将屏幕尺寸放大 5 倍。 小心内存使用! 尽管用户只能看到其中的 2%,但您正在绘制一个巨大的区域。
2)有两个版本的图像,一种高分辨率,一种低分辨率。 你应该能够非常快速地传输低分辨率,基本上你会得到“模糊”而不是“空白”瓷砖。 Apple 的示例代码 ZoomingPDFViewer 向您展示了如何执行此操作。
http://developer.apple.com/library/ios/ #samplecode/ZoomingPDFViewer/Introduction/Intro.html
当然,如果您想投入时间,两者的某种组合可能会起作用。
CATileLayer is one of those frustrating classes where it does one thing great, but has no flexibility to it.
At this point all that's left to us is creativity:
1) Make your scroll view huge. I tried 5x the size of the screen before I stopped seeing "blank" tiles. Be wary of memory use! You are drawing to a huge area even though the user only sees 2% of it.
2) Have two version of your image, one high res and one low res. you should be able to blit the low res very quickly and basically you get "blurry" instead of "blank" tiles. Apple's sample code ZoomingPDFViewer shows you how to do this.
http://developer.apple.com/library/ios/#samplecode/ZoomingPDFViewer/Introduction/Intro.html
Of course, some combination of the two might work if you want to invest the time.
您应该尝试在您希望显示的区域上调用 setNeedsDisplayInRect: 。 如果您想保持在图块边界内,可以使用tileSize 属性来计算图块边界。
但我不确定这是否有效,而且我们也不知道图块缓存机制是如何工作的。
You should try calling setNeedsDisplayInRect: on the areas you wish to display. If you want to keep within tile boundaries you can use the tileSize property to compute tile boundaries.
But I do not know for sure if this will work and we do not know how the tile caching mechanism works.