Skip to content

Instantly share code, notes, and snippets.

@ryanlintott
Created July 11, 2022 19:30
Show Gist options
  • Save ryanlintott/1930ad0595e1a24294c24aff7f939d6e to your computer and use it in GitHub Desktop.
Save ryanlintott/1930ad0595e1a24294c24aff7f939d6e to your computer and use it in GitHub Desktop.
A view that flips with a drag gesture.
//
// FlippableView.swift
// FrameUpExample
//
// Created by Ryan Lintott on 2022-07-11.
//
import SwiftUI
struct FlippableView: View {
@State private var dragOffset: CGFloat = .zero
@State private var predictedDragOffset: CGFloat = .zero
@GestureState private var isDragging: Bool = false
@State private var flips: Int = 0
var isFaceUp: Bool { (flips % 2) == 0 }
let flipDistance: CGFloat = 100
var angle: Angle { .radians(CGFloat(flips) * .pi) }
var dragAngle: Angle { angle + .degrees(180 * dragOffset / flipDistance) }
var body: some View {
VStack {
RoundedRectangle(cornerRadius: 20)
.fill(.blue)
.overlay(Text("Hello"))
.rotation3DEffect(dragAngle, axis: (0,1,0))
.frame(width: 200, height: 300)
.gesture(drag)
.onChange(of: isDragging) { isDragging in
if !isDragging { onDragEnded() }
}
Text("Face \(isFaceUp ? "Up" : "Down")")
Text("Flips: \(flips)")
Text("DragAngle: \(dragAngle.degrees)")
}
}
var drag: some Gesture {
DragGesture()
.updating($isDragging) { value, gestureState, transaction in
gestureState = true
}
.onChanged { value in
predictedDragOffset = value.predictedEndTranslation.width
dragOffset = value.translation.width
}
}
func onDragEnded() {
withAnimation(.spring().speed(0.5)) {
flips += Int((predictedDragOffset / flipDistance).rounded())
dragOffset = .zero
}
}
}
struct FlippableView_Previews: PreviewProvider {
static var previews: some View {
FlippableView()
}
}
@ryanlintott
Copy link
Author

2022-07-11 15 28 56

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment