Animierte Karten auf SwiftUI

Lassen Sie uns animierte Karten mit SwiftUI auf SwiftUI :



Ich wollte eine detaillierte Vorschau hinzufügen, aber die Größe des GIF ist nicht orthodox. Eine große Vorschau kann über den Link oder im Video-Tutorial angezeigt werden.


Wird benötigt


SwiftUI jetzt in der Beta und wird mit dem neuen Xcode installiert, der sich ebenfalls in der Beta befindet. Die gute Nachricht ist, dass der neue Xcode neben dem alten platziert werden kann und Sie kaum Schmerzen spüren können.



Sie können es über den Link im Abschnitt Applications herunterladen.


Möglicherweise haben Sie während der Arbeit mit SwiftUI Echtzeitvorschauen SwiftUI . Um es sowie einige Kontextmenüs zu aktivieren, müssen Sie die Beta- macOS Catalina installieren. Es wird nicht ohne Schmerzen auskommen. Ich habe nicht gewettet, also werde ich den Simulator auf die altmodische Weise ausführen.


Neues Projekt


Erstellen Sie eine Single View Application mit einem zusätzlichen Häkchen - SwiftUI :



Wechseln Sie zur Datei ContentView.swift . Der Erbe von PreviewProvider ist für die Vorschau verantwortlich. Da wir es nicht verwenden, belassen wir den minimal erforderlichen Code:


 import SwiftUI struct ContentView: View { var body: some View { } } 

Ich hoffe, es gibt bereits ein gemeinsames Verständnis über SwiftUI , wir werden nicht auf triviale Punkte SwiftUI .


Karten


Die Karten sind nacheinander angeordnet, daher verwenden wir ZStack . Ich HStack Sie daran erinnern, dass es zwei weitere Optionen zum Gruppieren von Elementen gibt: HStack - horizontal und VStack - vertikal. Zur Verdeutlichung:



Fügen Sie die erste Karte hinzu:


 struct ContentView: View { var body: some View { return ZStack { Rectangle() .fill(Color.black) .frame(height: 230) .cornerRadius(10) .padding(16) } } } 

Hier haben wir ein Rechteck hinzugefügt, schwarz gestrichen, Höhe 230pt , die Kanten um 10pt abgerundet und die Ränder allseitig auf 16pt .


Der Text auf der Karte wird dem ZStack Block nach dem Rechteck hinzugefügt:


 Text("Main Card") .color(.white) .font(.title) .bold() 

Führen Sie das Projekt aus, um das Zwischenergebnis anzuzeigen:



Aber es gibt drei davon!



MainCard wir MainCard Code aus:


 struct MainCard: View { var title: String var body: some View { ZStack { Rectangle() .fill(Color.black) .frame(height: 230) .cornerRadius(10) .padding(16) Text(title) .color(.white) .font(.largeTitle) .bold() } } } 

Der title wird im Initialisierer angezeigt. Dieser Text befindet sich auf der Karte. Fügen Sie der ContentView eine Karte ContentView . Gleichzeitig wird im Initialisierer ein neuer Parameter ContentView :


 struct ContentView: View { var body: some View { return MainCard(title: "Main Card") } } 

Wir wissen bereits, wie man den Code erstellt. Definieren Sie daher sofort eine Klasse für Hintergrundkarten:


 struct Card: View { var title: String var body: some View { ZStack { Rectangle() .fill(Color(red: 68 / 255, green: 41 / 255, blue: 182 / 255)) .frame(height: 230) .cornerRadius(10) .padding(16) Text(title) .color(.white) .font(.title) .bold() } } } 

Stellen Sie eine andere Farbe und einen anderen Stil für den Text ein. Der Rest des Codes wiederholt die schwarze MainCard . Fügen Sie ContentView zwei Hintergrundkarten ContentView . Die Karten werden nacheinander angeordnet, sodass wir sie in ZStack . ContentView Code:


 struct ContentView: View { var body: some View { return ZStack { Card(title: "Third card") Card(title: "Second Card") MainCard(title: "Main Card") } } } 

Hintergrundkarten befinden sich unter dem Schwarzen und sind bisher nicht sichtbar. Fügen Sie nach oben versetzt und von den Kanten gepolstert hinzu:


 Card(title: "Third card") .blendMode(.hardLight) .padding(64) .padding(.bottom, 64) Card(title: "Second Card") .blendMode(.hardLight) .padding(32) .padding(.bottom, 32) MainCard(title: "Main Card") 

Das Ergebnis ähnelt nun der Ankündigung zu Beginn des Tutorials:



Kommen wir zu den Gesten und damit zu den Animationen.


Gesten


Die Art und Weise, wie Gesten implementiert werden, zwingt mich dazu, das Karma zu verringern und eine toxische Bewertung abzugeben.



Bevor Sie den Code sehen, beachten Sie bitte, dass er als Beispiel auf developer.apple.com aufgeführt ist. Der erste Eindruck täuscht, in der Praxis hat es mir gefallen.


Deklarieren Sie die Aufzählung in ContentView :


 enum DragState { case inactive case dragging(translation: CGSize) var translation: CGSize { switch self { case .inactive: return .zero case .dragging(let translation): return translation } } var isActive: Bool { switch self { case .inactive: return false case .dragging: return true } } } 

DragState erleichtert das Arbeiten mit einer Geste. Hinzufügen von DragState- dragState zu ContentView :


 @GestureState var dragState = DragState.inactive 

Es wird Magie geben.



Überall dragState wo dragState verwendet wird, werden die neuen Werte automatisch angewendet. Deklarieren Sie eine Geste:


 let dragGester = DragGesture() .updating($dragState) { (value, state, transaction) in state = .dragging(translation: value.translation) } 

Fügen Sie der Hauptkarte eine Geste hinzu und stellen Sie den offset :


 MainCard(title: "Main Card") .offset( x: dragState.translation.width, y: dragState.translation.height ) .gesture(dragGester) 

Entspricht der Offset dem Wert des Parameters beim Zugriff? Nein, es wird immer gleich sein . Das ist Magie.


Karte wird folgen mit einem Finger mit der Maus, aber ohne Animationen:



Hintergrundkarten sollten auch ihre Position ändern ( zumindest wollten wir das ). Fügen Sie Code für sie hinzu, der an den Status der Geste gebunden ist. rotation3DEffect dreht die Karte, bis die Geste aktiv wird:


 Card(title: "Third card") .rotation3DEffect(Angle(degrees: dragState.isActive ? 0 : 60), axis: (x: 10.0, y: 10.0, z: 10.0)) .blendMode(.hardLight) .padding(dragState.isActive ? 32 : 64) .padding(.bottom, dragState.isActive ? 32 : 64) Card(title: "Second Card") .rotation3DEffect(Angle(degrees: dragState.isActive ? 0 : 30), axis: (x: 10.0, y: 10.0, z: 10.0)) .blendMode(.hardLight) .padding(dragState.isActive ? 16 : 32) .padding(.bottom, dragState.isActive ? 0 : 32) 

Wie sonst können Sie 3D verwenden, können Sie hier schauen. Ich habe auch blendMode hinzugefügt. Die Modi ähneln den Werkzeugen in Photoshop und Sketch.


Während die Änderungen nicht animiert angewendet werden, können wir sie beheben.


Animation


Sie werden überrascht sein, wie einfach es ist. Fügen Sie einfach eine Zeile hinzu:


 .animation(.spring()) 

Für jede Karte hinzufügen. Jetzt werden alle Änderungen animiert angewendet. In unserem Fall sind dies Einrückungsgrößen, 3D-Drehung und offset . Wenn Sie eine Animation mit Kurven benötigen, verwenden Sie den basic .


Dekorationen


Fügen Sie den Schatten und die Drehung der Hauptansicht hinzu, die an den Versatz gebunden sind:


 .rotationEffect(Angle(degrees: Double(dragState.translation.width / 10))) .shadow(radius: dragState.isActive ? 8 : 0) 

Wenn Sie das Projekt ausführen, wird die Referenz am Anfang des Lernprogramms angezeigt. Das Einschalten der Vorschau ist nicht sichtbar. Ziehen Sie die Karte zur Seite, um den Effekt zu sehen.



Für Suchende


→ Der Projektcode befindet sich im Repository


Es reicht aus, die Datei in das Projekt zu kopieren, es sind keine zusätzlichen Einstellungen erforderlich. Haben Sie keine Angst, dass so wenig Code eine der SwiftUI von SwiftUI .


Wenn Sie das Video bequemer ansehen möchten, schauen Sie sich das Tutorial an. Im Video verwende ich übrigens Echtzeitvorschauen.


Source: https://habr.com/ru/post/de456936/


All Articles