Written by 9:00 a.m. StreakFree

Willkommen im Spieleparadies – Teil 3 meines App-Projekts

Startbildschirm der "StreakFree"-App auf einem Smartphone. Oben werden "Level 4", "10 Punkte" und "Highscore 10" angezeigt. Darunter befindet sich ein Raster aus 16 Kreisen, von denen die oberen 10 blau gefüllt sind, um den Punktestand zu visualisieren. Am unteren Bildschirmrand gibt es zwei Buttons: "Rauchfrei bleiben" (blauer Text) und "Ich möchte rauchen" (grauer Text).

Disclaimer: Ich bin mir bewusst, dass Neumorphismus nicht für echte Apps / Produkte geeignet ist. Dieses Design ist weder barrierefrei, noch steht es für eine gute User-Experience. Dieses App-Projekt soll hauptsächlich Spaß machen und mir als Spielwiese dienen.

Wo Licht ist, ist auch Schatten.

Die Tragweite meiner Entscheidung, mich ans neumorphe Design zu wagen, dämmert mir nur langsam. Als ich aber Gemini mein Vorhaben schildere und die ersten Antworten erhalte, merke ich schnell, dass ich bei der Umsetzung nicht allzu viel Hilfe erwarten darf. Gemini beschreibt mir zwar einwandfrei, worauf es beim neumorphen Design ankommt, aber konkreten Code in Swift UI kann sie mir nicht nennen. Es bleibt halt ein nischiges Thema für Designer, das in der echten Welt kaum stattfindet.
Also schaue ich mich auf medium.com um und finde einige Artikel mit Code-Beispielen in Swift UI. Nachdem Gemini die entsprechenden Texte gelesen hat, haben wir eine gute Basis, um die Buttons und den Toggle umzusetzen.
Von letzterem hilft mir besonders ein View, der den Eindruck des Eingedrückten entstehen lässt.

Swift-Code für eine benutzerdefinierte SwiftUI View namens "DeepConcaveView". Diese Ansicht, erstellt von Erik Lolies, erzeugt einen konkaven 3D-Effekt durch die Überlagerung mehrerer abgerundeter Rechtecke mit Farbverläufen und Schatten, um Licht- und Schatteneffekte zu simulieren. Der Code zeigt die Definition der Struktur, ihrer Eigenschaften (wie Farben und Eckradius) und die Implementierung des visuellen Effekts im body.

Diesen kann ich sehr gut auch für die Punkte auf meiner Startseite nutzen. Gemini passt sekundenschnell die Form an und ich habe eingedrückte Kreise, die die Farbe ändern können.


Anschließend stellt sich mir die Frage, welches Element ich nutzen möchte, um Texte bzw. Zahlen anzuzeigen. Ich denke an meinen alten Taschenrechner und entdecke meinen alten Gameboy auf dem Schreibtisch. Ich werde also versuchen, ein altes Display nachzubauen.

Das Display

Da dieses Projekt bisher ohne den Einsatz von Figma auskommt und sämtliche Ideen nicht mehr als grobe Vorstellungen in meinem Kopf sind, schaue ich auf Dribbble, ob ich Designs von analogen Displays finde. Scheinbar ein Thema, mit dem sich nicht viele Menschen beschäftigen, doch schließlich finde ich ein Bild, das ungefähr dem entspricht, was ich mir vorstelle.


Im nächsten Schritt versuche ich mithilfe des Bildes die benötigten Ebenen zu definieren und erzähle Gemini, was ich benötige, um mein Display zu bauen. Die größte Herausforderung beim Display ist die korrekte Größenberechnung aller Ebenen mittels GeometryReader, da der Displayrand immer die gleiche Breite haben soll, die Displaybreite aber dynamisch ist. Gemini steigt später ratlos aus der Diskussion aus und ich überlege mir eine mögliche Lösung (die nach einem Wechsel auf Xcode 16, anscheinend aber nicht die von Apple präferierte ist, wie mir diverse Hinweise weismachen wollen).

Fortsetzung des Swift-Codes für eine benutzerdefinierte SwiftUI-Ansicht, die eine Benutzeroberfläche mit Neumorphismus-ähnlichen Effekten erstellt. Der Codeausschnitt (Zeilen ca. 49-153) zeigt die Implementierung von Anzeigelementen für Spielstatistiken (Level, Punkte, Highscore) und die Erzeugung von visuellen Tiefeneffekten für ein Raster. Dies wird durch eine komplexe Verschachtelung von RoundedRectangles, die Anwendung von Farbverläufen (LinearGradient), Schatten (shadow) und Überlagerungen (overlay) erreicht.

Bei der Schrift nutze ich für Zahlen einen Font, der klassischen 7-Segmentanzeigen nachempfunden ist. Für Texte kommt mir das Spiel Pokémon für den Gameboy in den Sinn, und ich suche eine ähnliche Schriftart heraus. Die Display-Komponente kann nun für verschiedene Zwecke eingesetzt werden – was ich anschließend auch zur Genüge tue.

Vergleich zweier Kernfunktionen der "StreakFree"-App: Links ein Motivationsbildschirm, der nach Erreichen von 11 Punkten positive Verstärkung und Gesundheitsinformationen liefert. Rechts ein Reflektionsbildschirm, der bei Rückfallgefahr den Nutzer an bisherige Erfolge (11 Mal widerstanden) erinnert und zur Selbstreflexion auffordert, bevor eine Entscheidung getroffen wird.

Immer im Wandel

Die Art und Weise, wie ich mit Gemini zusammenarbeite, ist immer im Wandel. Jeden Tag aufs neue muss ich mich auf mein Gegenüber einstellen. Es gibt Tage, da kann ein Gespräch scheinbar endlos zu unterschiedlichsten Themen geführt werden, an anderen kommt nach nur ein paar Nachrichten die Vergesslichkeit, Fehlermeldungen und schließlich die Kapitulation.


An einem Montag lerne ich eine entscheidende Lektion: Immer Fragen stellen! Ich hatte einen Bug in meiner Spiellogik entdeckt und wollte ihn schnell und unkompliziert von Gemini lösen lassen. In Gedanken war ich schon bei einem anderen Thema und wollte mich von dem Bug nicht lange aufhalten lassen.


Gemini legt also los mit den Lösungsvorschlägen und ich passe zügig meinen Code an. Die Fehlermeldungen in Xcode werden mehr und nach zwei Stunden funktioniert meine gesamte Spiellogik nicht mehr. Verdutzt stelle ich Gemini Fragen und stelle fest, dass bei den Lösungsvorschlägen meine vorhandene Logik gar nicht berücksichtigt wurde.


Es kostete mich eine Stunde, alle Änderungen rückgängig zu machen – das letzte Mal, dass ich unsauber bei der Versionierung war. Anschließend ging ich selbst auf Fehlersuche und entdeckte den Fehler schließlich bei einem Button in meinem ReflectionsView. Stolz präsentierte ich Gemini das Problem, wurde ausführlich für meine Entdeckung gelobt und bekam den angepassten Code.


Seitdem stelle ich Gemini deutlich mehr Fragen. Auch sehr naive Fragen. Bevor ich meinen Code anpasse, spreche ich mit Gemini die Lösung erst einmal theoretisch durch und erst wenn ich mir sicher bin, dass alle Aspekte berücksichtigt wurden, übernehme ich eine Lösung.

War da nicht noch was mit den Texten?

Gibt es beim Coding-Assistenten kaum Probleme mit sehr langen Antworten, so tut sich der Kreativ-Partner schwer, umfangreiche Texte zu erstellen. Ich starte ein neues Gespräch, um endlich meine Texte für die Punkte 1 bis 200 zu erhalten. Dieses Mal gebe ich auch gleich meine JSON-Formatierung mit an, um mir das umständliche Reinkopieren zu sparen.


Es zeigt sich, dass nicht mehr Texte als für 20 Punkte erstellt werden (also insgesamt 60 kurze Texte). Leider lässt sich auch nicht mehrmals hintereinander eine Abfrage für weitere 20 Punkte durchführen, da die Antworten an Qualität schnell abnehmen. Ich muss also immer wieder nachjustieren und werde am Ende nicht so richtig glücklich. Nach den Texten für die Punkte 1 bis 100 gönne ich Gemini und mir eine Verschnaufpause und verschiebe diese Aufgabe ein weiteres Mal.

Interaktion mit der KI Gemini Advanced, die eine verbesserte JSON-Struktur mit vielfältigen Textvarianten für ein Punktesystem (Punkte 21-40) liefert. Der Screenshot zeigt den JSON-Code mit Beispielen für die Punkte 21 bis 25, als Reaktion auf vorheriges Nutzerfeedback zur Vermeidung von Textwiederholungen.

One more thing.

Eine kleine Frage schlägt große Wellen: Wie würde die App eigentlich im Dark Mode aussehen? Die technische Umsetzung ist erstaunlich schnell erledigt. Ich lasse von Gemini meinen Code entsprechend anpassen und definiere die neuen Farben.


Doch was sich mir anschließend offenbart, zeigt primär viel Arbeit. Prinzipiell funktioniert das neumorphische Design auch im Dark Mode gleich. Es ist dann gewissermaßen ein dunkles statt helles haptisches Gerät. In der Theorie muss nur beim Licht und Schatten etwas nachgearbeitet werden, damit diese im Dark Mode schwächer sind.


In der Realität zeigt sich, dass bei mir viele Ebenen / Effekte sich im Dark Mode anders verhalten als erwartet. Kanten, die eigentlich klar sein sollten, sind an einigen Stellen unscharf. Auch sind einige Schatten versetzt und erzeugen einen ungewollten Effekt. Am Ende hilft der Dark Mode mir, mein Ursprungsdesign zu überprüfen und Schwachstellen zu identifizieren.


Damit der Nutzer die Wahl hat, ob er die App im hellen oder dunklen Modus nutzen möchte, kann das Aussehen in den App-Einstellungen ausgewählt werden. Beim Implementieren dieser Funktion bin ich ganz erstaunt, als ich feststelle, dass Gemini Advanced 1.5 jetzt auch Screenshots interpretieren und darauf reagieren kann. Ich bin mir bis jetzt nicht zu 100 Prozent sicher, ob dies zuverlässig funktioniert, aber bei der Arbeit an der Root.plist hat es mir sehr geholfen.

"StreakFree"-App Startbildschirm im Dark Mode: Zeigt aktuellen Spielstand (Level 4, 10 von 10 Punkten im Highscore) und die Auswahlmöglichkeiten "Rauchfrei bleiben" oder "Ich möchte rauchen". Zehn Kreise im Fortschrittsraster sind hellblau gefüllt auf dunklem Grund.

Wann ist man zufrieden?

Der Neumorphismus-Effekt wirkt nur, wenn Licht und Schatten akkurat gesetzt sind. Denn durch die monotone Farbgebung bleibt dem Betrachter schlicht nichts anderes, um Konturen und Elemente zu erkennen. Ist es bei einem Button noch einfach, ihn so wirken zu lassen, als würde er aus der Oberfläche herausschauen, so stellt mich das Display vor große Herausforderungen.


Ich habe Stunden damit verbracht, Licht und Schatten zu justieren und sehe nach wie vor Bereiche, die nicht stimmig sind. Die Art und Weise, wie Swift UI rendert, bleibt mir immer noch unverständlich.
Am Ende werde ich mich mit einem gewissen Ergebnis zufriedengeben müssen, aber noch versuche ich an all den kleinen Stellschrauben zu drehen, um den Effekt zu verbessern. Es wäre wirklich bedeutend leichter, wenn ich meine Augen nicht jahrelang geschult hätte, Fehler in Designs zu erkennen.

Ansicht des "Verlauf"-Bereichs der "StreakFree"-App auf einem Smartphone. Unter der Überschrift "Verlauf" wird ein einzelner Eintrag dargestellt: "Punkte: 11", gefolgt von dem Text "Ich hatte einen stressigen Termin und brauchte etwas zur Entspannung." und dem Zeitstempel "11.12.2024 10:48". In der oberen Navigationsleiste ist das Listen-Symbol (für Verlauf/Statistiken) hervorgehoben.

Ausblick

Für den vierten Teil meines Erfahrungsberichts möchte ich auf jeden Fall die Einschätzung meines Freundes, einem richtigen Entwickler, zu meinem Gemini-Code haben. Auch habe ich mittlerweile ein Developer-Abo und möchte die App im Store veröffentlichen. Zusätzlich steht auch noch der große Selbstversuch an, schließlich muss ich meine anfängliche Hypothese auch überprüfen.


Doch zuallererst werde ich mich den vielen Anmerkungen von Xcode 16 widmen müssen. Nach dem Wechsel von Version 15.2 scheint Xcode deutlich pingeliger mit meinem Code und mir zu sein, und meine Konsole füllt sich bei jedem Testen mit zig Anmerkungen und Fehlermeldungen.

Artikel teilen

Last modified: Juni 5, 2025

Close