2014-01-15 12 views
6

Ich möchte eine UIView Unterklasse haben, die ein ähnliches Verfahren wie setNeedsDisplay implementiert, mit der Ausnahme, dass neu gezeichnet wird in einem Hintergrund-Thread auftreten irgendwann soonish, (dh, dass in der Regel über drawRect: genannt würde) anstatt am Ende des aktuellen Update-Zyklus.UIView drawRect Mit treten in einem Hintergrundthread

Es könnte setNeedsAsynchronousDisplay genannt werden. Oder die bestehenden setNeedsDisplay könnte bekommen entführt und verursacht nicht am Ende des Zyklus neu zu zeichnen, oder was auch immer, solange es das Nachziehen nicht passiert auf dem Haupt-Thread blockiert Bildschirm kann die Aktualisierung eine Interaktion, bis sein abgeschlossen.

Bis zum erneuten Zeichnen kann die Ansicht weiterhin die aktuell gezeichnete Darstellung verwenden.

Ist etwas in dieser Richtung vernünftigerweise machbar?

Danke!

Antwort

10

Ja, es ist möglich. Sie müssen wahrscheinlich die Inhaltsansicht als Bild im Hintergrund erstellen und die Bilder in ein NSDictionary oder Array verschieben.

Während also Ihr Hintergrund die Bilder erzeugt, können Sie das Bild nur in der Darstellungsfunktion darstellen, indem Sie das Bild rendern, sofern das Bild erzeugt wurde.

Ein WWDC-Video, das zeigt, wie es geht: WWDC 2012 session 211 - Building Concurrent User Interfaces on IOS. Hier ist die Beschreibung des Videos:

Für eine gute Benutzererfahrung ist es wichtig, Ihre Anwendung reaktionsschnell zu halten, während es komplexe UI-Elemente rendert und Daten verarbeitet. Erfahren Sie, wie Sie die Parallelität auf der UIKit-Ebene zum Ausführen von Zeichnungen und anderen allgemeinen Operationen verwenden, ohne die Benutzerinteraktion zu blockieren.

+0

Danke, das klingt nach einem guten Lead. – Benjohn

+0

Nachdem ich das Video gesehen hatte, war ich sehr aufgeregt und versuchte sogar selbst eines zu bauen. Es ist praktischer für Zellenansichten, die nicht viele Interaktionen wie Schaltflächen oder Hervorhebungsstatus haben. Lass es mich wissen, wenn du es selbst gebaut hast. –

+0

Danke @Ethan, das klingt sicherlich hilfreich aus der Beschreibung. Ich schaue mir das heute an. – Benjohn

-3

Nr. Anzeigen Die Zeichnung muss im Vordergrund erscheinen. Apple macht das in ihren Dokumenten sehr deutlich.

EDIT: Sie haben Recht, dass Sie Core Graphics im Hintergrund zeichnen können, solange es nicht in den Zeichenmethoden eines UIView-Objekts ist. Sie müssten die Zeichnung im Hintergrund erstellen und dann eine Nachricht an den Hauptthread senden, um das Ansichtsobjekt nach Abschluss der Zeichnung zu aktualisieren.

würde ich vorschlagen, nicht setNeedsDisplay außer Kraft zu setzen versucht. Fügen Sie stattdessen Ihre neue setNeedsAsynchronousDisplay-Methode hinzu. Bei dieser Methode müssen Sie den Rendering-Code mithilfe von GCD-Aufrufen in eine asynchrone Warteschlange einreihen. Sobald der Rendervorgang abgeschlossen ist, muss der Rendering-Code eine setNeedsDisplay-Nachricht an self im Hauptthread senden.

Dann in der DrawRect-Methode der Unterklasse nach vorgerenderten Bildern suchen und diese in den Kontext der Ansicht zeichnen, statt den normalen Code.

Ein Nachteil davon ist, dass Sie durch das Implementieren von DrawRect das Rendering verlangsamen können, weil das System dies aufruft, anstatt andere, effizientere Dinge zu tun, um den Inhalt Ihrer Ansicht zu rendern.

+0

Vielen Dank @Duncan C, aber ich glaube nicht, dass dies der Fall von iOS 4 für Core Graphics-Operationen (aber nicht ihre UI-Wrapper) ist. Sehen Sie bitte diesen [technischer Hinweis bei Apple] (https://developer.apple.com/library/ios/qa/qa1637/_index.html). Ich vermute, dass UIView Updates im Hauptthread sein müssen, aber das bedeutet nicht, dass die Zeichnung nicht im Hintergrund auf einer anderen Oberfläche passieren und dann ausgetauscht werden kann. Ich bin auf Ideen/Vorschläge/Best Practice/komplette Lösungen dafür. – Benjohn

+0

Ich habe noch nie "drawRect inContext" verwendet, vielleicht einen Versuch wert. –