2009-07-15 6 views
12

Auf dem iPhone (obwohl ich denke, es ist eine ebenso gültige Frage in Cocoa) Ich habe eine UIScrollView um eine UIView von einem CATiledLayer unterstützt. Standardmäßig werden alle nicht zwischengespeicherten/nicht abgerufenen Kacheln geladen, wenn mein Ansichtsfenster über einen leeren Abschnitt von CATiledLayer scrollt.Kacheln in einem CATiledLayer vorladen/vordisponieren?

Was ich gerne wissen würde, ist, wenn es eine Möglichkeit gibt, CATiledLayer zu starten, um eine Kachel zu laden, die nicht aktiv angezeigt wird? Ich möchte zum Beispiel alle Kacheln, die an die aktuell angezeigte Kachel angrenzt, vorab laden, während sie sich noch nicht im Bildschirm befinden, und so verhindern, dass ein leerer Bildschirm blinkt, der nach dem asynchronen Laden in das Bild eingeblendet wird.

Irgendwelche Ideen?

+0

Haben Sie das herausgefunden? Ich würde gerne wissen, wie du es gemacht hast, wenn du es getan hast. –

+0

Nein. Niemals getan. :(Mit setNeedsDisplayInRect: funktioniert, um den Inhalt einer bereits geladenen Kachel zu aktualisieren, aber es scheint nicht zu laden. – jemmons

Antwort

14

Ich glaube nicht, CATiledLayer wird tun, was Sie wollen. Es gibt jedoch noch ein paar andere Optionen. Zuerst kann man die Kachel Fade-in deaktivieren und es sofort wie dies mit etwas zeigen:

@interface NoFadeTiledLayer : CATiledLayer { 
} 
@end 

@implementation NoFadeTiledLayer 
+ (CFTimeInterval)fadeDuration { 
    return 0.0; 
} 
@end 

@implementation MyViewWithTiledLayer 
+ (Class)layerClass { 
    return [NoFadeTiledLayer class]; 
} 
... 
@end 

Zweitens können Sie Ihre eigenen tun Pre-Fetch und Caching der benachbarten Fliesen, so dass sie bereit sind, zu gehen, wenn CATileLayer ruft drawLayer: inContext auf. Ich würde scrollViewDidScroll implementieren: und scrollViewDidZoom: um die angrenzenden Kacheln und levelOfDetail zu bestimmen. Führen Sie dann einen Cache-Lookup durch und fügen Sie einer Pre-Fetch/Render-Warteschlange alle nicht vorhandenen hinzu. Ein Hintergrund-Thread könnte die Warteschlange bedienen und nachfolgende Scrolls oder Zooms würden die Warteschlange löschen und neu erstellen. Dann habe drawLayer: inContext überprüfe zuerst den Cache und hole/render wenn nötig.

+1

Ich habe diesen Ansatz zu Precaching (einschließlich der Nicht-Fade-Dauer Layer-Unterklasse und es scheint nicht viel zu helfen, leider. Ich bin ratlos, warum, es klingt sicherlich wie ein guter Ansatz. –

0

Sie sollten versuchen, setNeedsDisplayInRect aufzurufen: in den Bereichen, die Sie anzeigen möchten. Wenn Sie innerhalb der Kachelgrenzen bleiben möchten, können Sie mit der Eigenschaft kachelSize die Kachelgrenzen berechnen.

Aber ich weiß nicht sicher, ob das funktioniert und wir nicht wissen, wie der Kachel-Mechanismus funktioniert.

4

CATileLayer ist eine dieser frustrierenden Klassen, in denen es eine Sache großartig macht, aber keine Flexibilität hat.

An dieser Stelle alles, was uns übrig bleibt, ist Kreativität:

1) Machen Sie Ihre Scroll riesigen sehen. Ich versuchte 5x die Größe des Bildschirms, bevor ich "leere" Fliesen sah. Vorsicht beim Speichern! Sie zeichnen auf einen riesigen Bereich, obwohl der Benutzer nur 2% davon sieht.

2) Haben Sie zwei Version Ihres Bildes, eine hohe Res und eine niedrige Res. Sie sollten in der Lage sein, die niedrigen res sehr schnell zu blitschen und im Grunde erhalten Sie "verschwommene" statt "leere" Kacheln. Apples Beispielcode ZoomingPDFViewer zeigt Ihnen, wie Sie dies tun.

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

Natürlich könnte eine Kombination der beiden funktionieren, wenn Sie die Zeit investieren wollen.

+0

Alle großen Ideen. Ich wünschte, ich könnte zwei Antworten nennen! – jemmons