SwiftUI | Animieren Sie diese Pfadform
Ich habe folgenden Fall:
Ich möchte diese Form mit einer benutzerdefinierten Animation umdrehen. Ich weiß nicht, wie ich es richtig beschreiben soll.
Immer wenn ich auf den Pfeil tippe, sollte er sich in den anderen verwandeln . Ohne zu drehen, zu drehen usw. einfach zu transformieren.
Wenn das nicht präzise genug ist, können Sie dies gerne kommentieren!
Demo-Code
struct ContentView: View {
@State private var change = false
private let arrowWidth: CGFloat = 80
var body: some View {
Path { path in
path.move(to: .zero)
path.addLine(to: CGPoint(x: arrowWidth/2, y: change ? -20 : 20))
path.move(to: CGPoint(x: arrowWidth/2, y: change ? -20 : 20))
path.addLine(to: CGPoint(x: arrowWidth, y: 0))
}
.stroke(style: StrokeStyle(lineWidth: 12, lineCap: .round))
.frame(width: arrowWidth)
.foregroundColor(.green)
.animation(.default)
.onTapGesture { change.toggle() }
.padding(.top, 300)
}
}
Wie Sie jetzt sehen können, hat es keine Animation. Ich habe keine Ahnung, wie es geht.
Jede Hilfe wird sehr geschätzt. Vielen Dank!
Hinweis: Ich kann dies nicht mit zwei abgerundeten Rechtecken + einfachem Drehen tun, da ich eine Deckkraftanimation habe, die die Überlappung sichtbar macht.
Antworten
Hier ist ein möglicher Ansatz: Verschieben Sie den Pfad in eine benutzerdefinierte Form und ändern Sie die Parameter als animierbare Eigenschaft. Getestet mit Xcode 12 / iOS 14
struct MyArrow: Shape {
var width: CGFloat
var offset: CGFloat
var animatableData: CGFloat {
get { offset }
set { offset = newValue }
}
func path(in rect: CGRect) -> Path {
Path { path in
path.move(to: .zero)
path.addLine(to: CGPoint(x: width/2, y: offset))
path.move(to: CGPoint(x: width/2, y: offset))
path.addLine(to: CGPoint(x: width, y: 0))
}
}
}
struct ContentView: View {
@State private var change = false
private let arrowWidth: CGFloat = 80
var body: some View {
MyArrow(width: arrowWidth, offset: change ? -20 : 20)
.stroke(style: StrokeStyle(lineWidth: 12, lineCap: .round))
.frame(width: arrowWidth)
.foregroundColor(.green)
.animation(.default)
.onTapGesture { change.toggle() }
.padding(.top, 300)
}
}