I've noticed that UIView.animate is less quirky and 'smoother' with less lag than using withAnimation { } and the general Animation class in SwiftUI. That being said, I have some Flashcards that I'm flipping. The problem is, when I use withAnimation { }, there's some lag that sometimes makes it look like the card isn't even flipping (it looks like just the content inside the card instantly changes). I have 5 flashcards in a ScrollView rendered at the same time. How can I use UIView.animate() to animate the change?
struct Flashcard<Front, Back>: View where Front: View, Back: View {
var front: () -> Front
var back: () -> Back
@State var flipped: Bool = false
@State var flashcardRotation = 0.0
@State var contentRotation = 0.0
init(@ViewBuilder front: @escaping () -> Front, @ViewBuilder back: @escaping () -> Back) {
self.front = front
self.back = back
}
var body: some View {
ZStack {
if flipped {
ZStack {
back()
VStack {
HStack {
Spacer()
Button(action: {
flipFlashcard()
}, label: {
Text("Flipper")
}).padding(5)
}
Spacer()
}
}
} else {
ZStack {
front()
VStack {
HStack {
Spacer()
Button(action: {
flipFlashcard()
}, label: {
Text("Flipper")
}).padding(5)
}
Spacer()
}
}
}
}
.rotation3DEffect(.degrees(contentRotation), axis: (x: 0, y: 1, z: 0))
.frame(height: 150)
.frame(maxWidth: .infinity)
.padding(.horizontal)
.rotation3DEffect(.degrees(flashcardRotation), axis: (x: 0, y: 1, z: 0))
}
func flipFlashcard() {
let animationTime = 0.25
// My attempt at using UIView.animate()
// UIView.animate(withDuration: 5, animations: {
// flashcardRotation += 180
// })
withAnimation(Animation.linear(duration: animationTime)) {
flashcardRotation += 180
}
// My attempt at using UIView.animate()
// UIView.animate(withDuration: 0.001, delay: animationTime / 2, animations: {
// contentRotation += 180
// flipped.toggle()
// }, completion: nil)
withAnimation(Animation.linear(duration: 0.001).delay(animationTime / 2)) {
contentRotation += 180
flipped.toggle()
}
}
}
