I have applied a drag gesture with some action to the Image views inside Foreach view, but when I drag an image - it visually drags all the images within the parent view and even in the other Foreach view with images. The action applied to the selected image works properly though. How can I make only selected image move and all others stay still?
Gesture variables:
@State var position = CGSize.zero
@GestureState private var dragOffset = CGSize.zero
There is the code:
ScrollView(.horizontal) {
HStack(alignment: .center, spacing: 0) {
ForEach ((0..<player.playersCards.count), id: \.self) {number in
VStack {
Image(player.playersCards[number].pic)
.resizable()
.modifier(CardStyle())
.offset(dragOffset)
.gesture(
DragGesture()
.updating($dragOffset, body: { (value, state, transaction) in
state = value.translation
})
.onEnded({ (value) in
self.position.height += value.translation.height
self.position.width += value.translation.width
//player's turn
})
)
.animation(.spring())
Text("\(ai.getPower(card: player.playersCards[number]))")
.modifier(TextModifier())
}
}
}
}
It’s because all of your images in forEach
are set to single @GestureState
property, so when one is dragged all mapped to it gets dragged on body refresh. You can have separate array
that store each drag state of your card at particular index uniquely.
struct LanguageView: View {
@State var position = CGSize.zero
@GestureState private var dragOffset:[CGSize]
init() {
let dragOffsets = [CGSize](repeating: CGSize.zero, count: 5) // Initialise with your model array count
_dragOffset = GestureState(wrappedValue: dragOffsets)
}
var body: some View {
ScrollView(.horizontal) {
HStack(alignment: .center, spacing: 5) {
ForEach ((0..<5)) {number in
VStack {
Image("ABC")
.resizable()
.frame(width: 300, height: 100)
//.modifier(CardStyle())
.offset(dragOffset[number])
.gesture(
DragGesture()
.updating($dragOffset, body: { (new, existing, transaction) in
existing[number] = new.translation
})
.onEnded({ (value) in
self.position.height += value.translation.height
self.position.width += value.translation.width
//player's turn
})
)
.animation(.spring())
Text("Foo")
// .modifier(TextModifier())
}
}
}
}.frame(width: 500, height: 100)
}
}