I am currently developing an App shows a user his plant boxes and some measurements (like ground humidity, temperature etc) Each plant box has some plants inside it, which are being displayed in a detail view. I want the user to be able to drag one of the plants to a corner in order to remove it. Currently I have this implementation:
@GestureState private var dragOffset = CGSize.zero
var body: some View {
//Plants Headline
VStack (spacing: 5) {
Text("Plants")
.font(.headline)
.fontWeight(.light)
//HStack for Plants Images
HStack (spacing: 10) {
//For each that loops through all of the plants inside the plant box
ForEach(plantBoxViewModel.plants) { plant in
//Image of the individual plant (obtained via http request to the backend)
Image(base64String: plant.picture)
.resizable()
.clipShape(Circle())
.overlay(Circle().stroke(Color.white, lineWidth: 2))
.offset(x: self.dragOffset.width, y: self.dragOffset.height)
.animation(.easeInOut)
.aspectRatio(contentMode: .fill)
.frame(width: 70, height: 70)
.gesture(
DragGesture()
.updating(self.$dragOffset, body: { (value, state, transaction) in
state = value.translation
})
)
}
}
}
}
It looks like the following: Screenshot of Code Snippet
However, when I start dragging, both images move. I think it is because the offset of both images gets bound to the same variable (DragOffset). How can I accomplish that only 1 image is moving?
I thought about implementing some sort of array that maps the index of the plant to a specific offset but I wouldn't know how to implement it into the gesture. Thanks for any help!
Here is possible approach - to keep selection during drag. Tested with Xcode 11.4 / iOS 13.4.
@GestureState private var dragOffset = CGSize.zero
@State private var selected: Plant? = nil // << your plant type here
var body: some View {
//Plants Headline
VStack (spacing: 5) {
Text("Plants")
.font(.headline)
.fontWeight(.light)
//HStack for Plants Images
HStack (spacing: 10) {
//For each that loops through all of the plants inside the plant box
ForEach(plantBoxViewModel.plants) { plant in
//Image of the individual plant (obtained via http request to the backend)
Image(base64String: plant.picture)
.resizable()
.clipShape(Circle())
.overlay(Circle().stroke(Color.white, lineWidth: 2))
.offset(x: self.selected == plant ? self.dragOffset.width : 0,
y: self.selected == plant ? self.dragOffset.height : 0)
.animation(.easeInOut)
.aspectRatio(contentMode: .fill)
.frame(width: 70, height: 70)
.gesture(
DragGesture()
.updating(self.$dragOffset, body: { (value, state, transaction) in
if nil == self.selected {
self.selected = plant
}
state = value.translation
}).onEnded { _ in self.selected = nil }
)
}
}
}
}