Created
January 23, 2023 19:11
-
-
Save AdamWhitcroft/5cb4326997b16cff48778cfd05dc43af to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// Created by Adam Whitcroft on 2023-01-23. | |
// | |
import SwiftUI | |
struct SimpleDragGesture: View { | |
@State private var focussedItem: String = "middle" | |
@State private var offset = CGSize.zero | |
@State private var accumulatedOffset = CGSize.zero | |
// constants | |
let cardSize: CGFloat = 60 | |
let springAnimation: Animation = .interpolatingSpring(stiffness: 400, damping: 20) | |
var body: some View { | |
VStack { | |
HStack(spacing: cardSize) { | |
Rectangle() | |
.fill(focussedItem == "left" ? .red : .gray) | |
.frame(width: cardSize, height: cardSize) | |
Rectangle() | |
.fill(focussedItem == "middle" ? .red : .gray) | |
.frame(width: cardSize, height: cardSize) | |
Rectangle() | |
.fill(focussedItem == "right" ? .red : .gray) | |
.frame(width: cardSize, height: cardSize) | |
} | |
.offset(x: offset.width) | |
.contentShape(Rectangle()) | |
.gesture ( | |
DragGesture() | |
.onChanged { gesture in | |
withAnimation(springAnimation) { | |
offset = CGSize( | |
width: gesture.translation.width + self.accumulatedOffset.width, | |
height: gesture.translation.height + self.accumulatedOffset.height | |
) | |
// clamp overdrag left | |
if offset.width > cardSize * 2.5 { | |
offset.width = cardSize * 2.5 | |
} | |
// clamp overdrag right | |
if offset.width < -cardSize * 2.5 { | |
offset.width = -cardSize * 2.5 | |
} | |
} | |
} | |
.onEnded { gesture in | |
// left item | |
if offset.width > cardSize { | |
focussedItem = "left" | |
withAnimation(springAnimation) { | |
offset.width = cardSize * 2 | |
} | |
accumulatedOffset.width = offset.width | |
} | |
// right item | |
else if offset.width < -cardSize { | |
focussedItem = "right" | |
withAnimation(springAnimation) { | |
offset.width = -cardSize * 2 | |
} | |
accumulatedOffset.width = offset.width | |
} | |
// middle | |
else { | |
focussedItem = "middle" | |
withAnimation(springAnimation) { | |
offset = .zero | |
} | |
accumulatedOffset.width = offset.width | |
} | |
} | |
) | |
} | |
} | |
} | |
struct SimpleDragGesture_Previews: PreviewProvider { | |
static var previews: some View { | |
SimpleDragGesture() | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment