Ich erstelle einen Syntax-Highlighter für das iPhone und um Text mit mehreren Formaten anzuzeigen, habe ich UIView unterklassifiziert und die drawRect:
-Methode so geändert, dass jede Zeile mit der richtigen Syntax angezeigt wird Hervorhebung (Hervorhebung erfolgt früher mit RegEx, Text wird mit CGContextShowTextAtPoint()
Zeile für Zeile gezeichnet). Alles funktioniert gut, ich speichere jede Textzeile als NSString in einem NSMutableArray, ich handle mit der Tastatur über ein verstecktes UITextField und seine Delegate-Methoden, der Cursor ist ein blinkender CALayer, der mit Berührungen verschoben werden kann und ich habe eine benutzerdefinierte Bildlaufansicht das Scrollen behandelt. Ich habe jedoch zwei Probleme, die ich kann meinen Kopf nicht scheinen um zu wickeln:Erstellen einer benutzerdefinierten Textzeichnungsansicht
Zeilenumbruch, gerade jetzt der Text gerade hält das linke Ende des Bildschirms abgehend. Um die Dinge schnell zu halten, zeichne ich nur die Teile der Ansicht neu, die sich geändert haben (normalerweise nur die zu bearbeitende Zeile, manchmal aber auch die darunter liegenden Zeilen, z. B. wenn Sie auf die Hälfte des Dokuments zurück drücken) mit
setNeedsDisplayInRect:
. Dies erschwert das Umbrechen von Wörtern, da Sie dann mehr als eine Zeile auf dem Bildschirm zeichnen müssen, obwohl es immer noch nur ein Objekt im Array ist.UIViews haben eine maximale Inhaltsgröße von 1024x1024, was etwa 64 Zeilen entspricht. Ich brauche die Fähigkeit, mehr als das anzuzeigen. Ich denke darüber nach, mehrere CALayer hintereinander zu verwenden, aber ich habe Probleme beim Zeichnen von Inhalt auf die Ebenen (unter Verwendung von
drawLayer:inContext:
unddrawInContext:
).
Also meine Fragen sind:
- Hat jemand irgendwelche haben, auch allgemeine, Vorschläge, wie eine dieser beiden Punkte zu erreichen. Oder,
- Hat jemand bereits eine benutzerdefinierte Text-Zeichnung-Ansicht geschrieben, die diese Dinge behandelt, die ich stattdessen verwenden könnte.
Danke,
Kyle
EDIT: Das Scrollen Problem ziemlich gelöst, aber ich immer noch Probleme mit word-wrap bin. Mein Problem ist, dass alles Zeile für Zeile erledigt wird: Die Ansicht wird jeweils um eine Zeile aktualisiert, der Text wird als ein Array von Zeilen gespeichert, der Textmarker markiert jeweils eine Zeile usw. und hat einen einzelnen Index im Array (eins Textzeile) nehmen mehrere Zeilen auf dem Bildschirm auf, wirft einige Probleme auf, zum Beispiel musste ich meinen eigenen beweglichen Cursor implementieren und wenn Sie den Cursor bewegen, muss er in der Lage sein, eine Displayzeile zu drehen (gefunden durch Teilen von touch.x mit Zeilenhöhe) in eine Textzeile (ein Index im Array). Irgendwelche Ideen?
Danke für Ihre Antwort, wissen Sie, ob drawAtPoint: ist deutlich langsamer als CGContextShowTextAtPoint()? Ich nehme an, es ist, weil Obj-C-Funktionen im Allgemeinen langsamer als C-Funktionen sind, aber das ist nicht immer der Fall. – Kyle
Tatsächlich ist der Aufwand beim Aufruf von Obj-C-Methoden gegenüber C-Funktionen minimal, also würde ich mir darüber keine Sorgen machen. Allerdings sind diese Routinen viel langsamer, weil sie auf dem iPhone Webkit verwenden, um das Textlayout auszuführen. Ob dies zu einem Problem für Sie wird, hängt davon ab, wie oft Sie den Text erneut rendern. Ich benutze es überall in Pi Cubed, die sehr gute Renderleistung hat: http://www.sunsetlakesoftware.com/picubed. –
Nur für zukünftige Referenz habe ich einen einfachen Benchmark, der DrawAtPoint mit CGContextShowTextAtPoint verglichen. Ich zeichnete 36 Zeichenketten 1000 mal an zufälligen y-Stellen über den Bildschirm und hier ist, was ich bekam (auf einem 1g iPod touch): CGContextShowTextAtPoint - 99 Refreshes/Sek., DrawAtPoint - 75 Refreshes/Sek. Die CG-Methode ist also deutlich schneller. – Kyle