Skip to content

Instantly share code, notes, and snippets.

@raphschwander
Last active December 15, 2022 07:24
Show Gist options
  • Save raphschwander/95a11c6e516bd962fadee6c321652284 to your computer and use it in GitHub Desktop.
Save raphschwander/95a11c6e516bd962fadee6c321652284 to your computer and use it in GitHub Desktop.
Flip View - SwiftUI
// MARK: - Usage
struct ContentView: View {
@State private var isFlipped = false
var body: some View {
FlipView(duration: 0.75,
perspective: 0.5,
isFlipped: $isFlipped) {
Color.red
} back: {
Color.blue
}
.frame(width: 300, height: 300)
.padding()
.onTapGesture {
isFlipped.toggle()
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
// MARK: - FlipView
struct FlipView<Front: View, Back: View>: View {
var duration: Double = 1.0
var axis: (x: CGFloat, y: CGFloat, z: CGFloat) = (x: 0, y: 1, z: 0)
var perspective: CGFloat = 1
@Binding var isFlipped: Bool
private var durationAndDelay: Double { duration / 2 }
@ViewBuilder let front: Front
@ViewBuilder let back: Back
@State private var frontDegree = 0.0
@State private var backDegree = -90.0
var body: some View {
ZStack {
back
.rotation3DEffect(Angle(degrees: backDegree), axis: axis, perspective: perspective)
front
.rotation3DEffect(Angle(degrees: frontDegree), axis: axis, perspective: perspective)
}
.onChange(of: isFlipped) { isFlipped in
if isFlipped {
withAnimation(.linear(duration: durationAndDelay)) {
frontDegree = 90
}
withAnimation(.linear(duration: durationAndDelay).delay(durationAndDelay)) {
backDegree = 0
}
} else {
withAnimation(.linear(duration: durationAndDelay)) {
backDegree = -90
}
withAnimation(.linear(duration: durationAndDelay).delay(durationAndDelay)) {
frontDegree = 0
}
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment