I would like to be able to use multiple gestures against a number of images. In the code below, when I use the tap (3 times) gesture, it works correctly off the clicked card, same with the long press. However, when I try to drag 1 image, all of them are dragged together. I guess it has something to do with being in the ForEach view?
Thanks for looking at this and helping me get out of the rut I have dragged myself into!
Here is the code (you can use any images to test, I used playing cards):
import SwiftUI
struct ContentView: View {
enum DragState {
case inactive
case dragging(translation: CGSize)
var translation: CGSize {
switch self {
case .dragging(let translation): return translation
default:return CGSize.zero}}}
@GestureState var pressing: Bool = false
@GestureState var dragState = DragState.inactive
@State var viewDragState = CGSize.zero
@State var p1Hand: [String] = ["2_of_hearts", "3_of_hearts", "4_of_hearts", "5_of_hearts"]
@State var discardDeck: [String] = []
@State var p1TM1: [String] = []
@State var expand: Bool = false
var translationOffset: CGSize {
return CGSize(width: viewDragState.width + dragState.translation.width, height: viewDragState.height + dragState.translation.height)}
var body: some View {
ZStack {
ForEach(0..<p1Hand.count, id: \.self) {
cardIndex in CardView (card: p1Hand[cardIndex], cardIndex: cardIndex)
// 3 taps to move to different array
.onTapGesture(count: 3, perform: {
discardDeck.append(p1Hand[cardIndex])
print("discard: \(discardDeck)")
})
// long press put in another array
.gesture(LongPressGesture(minimumDuration: 1)
.updating($pressing)
{value,state,transaction in state = value
transaction.animation = Animation.easeInOut(duration: 0.5)
}
.onEnded {
value in expand = true
p1TM1.append(p1Hand[cardIndex])
print("p1TM1: \(p1TM1)")
})
// drag card to group
.gesture(DragGesture(minimumDistance: 5)
.updating($dragState) { value, state, translation in state = .dragging(translation: value.translation)
}.onEnded { value in
self.viewDragState.height += value.translation.height
self.viewDragState.width += value.translation.width
print("card(s) dragged")
})
.offset(translationOffset)
}
}
}
}
struct CardView: View {
var card: String
var cardIndex: Int
var body: some View {
Image(card)
.resizable()
.frame(width: 40, height: 60)
.position(x: 40 + CGFloat(cardIndex * 25), y:75)
}
}
#Preview {
ContentView()
}