2009-07-15 2 views
12

На iPhone (хотя я предполагаю, что это одинаково важный вопрос в Cocoa) У меня есть UIScrollView вокруг UIView, поддерживаемый CATiledLayer. По умолчанию он работает, чтобы загрузить любые незашифрованные/незакрашенные фрагменты, когда мой видовой экран прокручивается над пустой частью CATiledLayer.Preload/preisplay плитки в CATiledLayer?

Что я хотел бы знать, есть ли способ вызвать CATiledLayer для загрузки плитки, которая не отображается активно? Я хотел бы, например, предварительно загрузить все плитки, прилегающие к отображаемой в данный момент плитке, в то время как они все еще находятся вне экрана, что позволяет избежать мигания пустого экрана, который исчезает в изображении после его асинхронной загрузки.

Любые идеи?

+0

Вы поняли это? Мне бы очень хотелось узнать, как вы это сделали, если позволили. –

+0

Nope. Никогда не делал. :(Использование setNeedsDisplayInRect: работает, чтобы обновить содержимое уже загруженной плитки, но, похоже, не вызывает ее предварительной загрузки. – jemmons

ответ

14

Я не думаю, что 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. Затем выполните поиск в кеше и добавьте любой, отсутствующий в очередь pre-fetch/render. Фоновый поток может обслуживать очередь, а последующие прокрутки или масштабирования будут очищать и перестраивать очередь. Затем выполните drawLayer: inContext сначала проверяет кеш и только при необходимости извлекает/отрисовку.

+1

Я пробовал этот подход к преципированию (в том числе подкласс уровня продолжительности бездействия), и, похоже, он мало помогает, к сожалению. Я не понимаю, почему, это, безусловно, звучит как хороший подход. –

0

Вам следует попробовать позвонить setNeedsDisplayInRect: в областях, которые вы хотите отобразить. Если вы хотите сохранить границы плитки, вы можете использовать свойство tileSize для вычисления границ плитки.

Но я не знаю точно, если это будет работать, и мы не знаем, как работает механизм кэширования плитки.

4

CATileLayer - один из тех разочаровывающих классов, где он отлично справляется, но не имеет никакой гибкости.

На данный момент все, что осталось нам творчество:

1) Сделайте свой свиток просмотра огромно. Я попробовал размер экрана 5 раз, прежде чем я перестаю видеть «чистые» плитки. Будьте осторожны в использовании памяти! Вы рисуете огромную область, хотя пользователь видит только 2%.

2) У вас есть две версии вашего изображения, один высокий res и один низкий res. вы должны быстро разбить низкое разрешение, и в основном вы получаете «размытость» вместо «пустой» плитки. Пример кода Apple ZoomingPDFViewer показывает, как это сделать.

http://developer.apple.com/library/ios/#samplecode/ZoomingPDFViewer/Introduction/Intro.html

Конечно, некоторая комбинация этих двух может работать, если вы хотите инвестировать время.

+0

Все замечательные идеи. Хотелось бы, чтобы я мог назвать два ответа! – jemmons

Смежные вопросы