SwiftUI - Drag and Drop - drags adjacent views

I have a simple HStack that has 3 of the same views below in it like columns). They all have a draggable text field. Weird thing is when I drag one, the adjacent DayView.Text fields also drag. As if they all share the same drag gesture. Is there a way to prevent that?


struct DayView: View {

@GestureState var dragState = DragState.inactive

@State var viewDragState = CGSize(width: 0, height: 120)

var translationOffset: CGSize {

return CGSize(width: 0, height: viewDragState.height + dragState.translation.height)

}

enum DragState {

case inactive

case dragging(translation: CGSize)

var translation: CGSize {

switch self {

case .dragging(let translation):

return translation

default:

return .zero

}

}

}

var body: some View {

let dragGesture = DragGesture()

.updating($dragState) { value, state, transaction in

state = .dragging(translation: value.translation)

}

.onEnded { value in

self.viewDragState.height += value.translation.height

self.viewDragState.width += value.translation.width

}

return GeometryReader { geometry in

ZStack(alignment: .top) {

VStack(spacing: 0) {

ForEach(0..<24) {_ in

Text("").frame( height: 60)

Divider()

}

}

Text("Meet with Test 2-4").frame(width: geometry.size.width, height: 120, alignment: .topLeading).background(Color.red)

.offset(self.translationOffset)

.gesture(dragGesture)

}

}

}

}

Replies

We do not see the HStack in your code.

Could you post this part of code as well


I have tested with this:

struct ContentView: View {
    var body: some View {
        HStack {
            DayView().background(Color.blue)
            DayView().background(Color.yellow)
            DayView().background(Color.green)
        }.padding(10).border(Color.red, width: 3)
    }
}



It works, I can move each Text("Meet with Test 2-4") independantly.

Did you solve your problem ?


Full code:

struct DayView: View {
     
    @GestureState var dragState = DragState.inactive
    @State var viewDragState = CGSize(width: 0, height: 120)
 
    var translationOffset: CGSize {
        return CGSize(width: 0, height: viewDragState.height + dragState.translation.height)
    }
 
    enum DragState {
        case inactive
        case dragging(translation: CGSize)
     
        var translation: CGSize {
            switch self {
            case .dragging(let translation):
                return translation
            default:
                return .zero
            }
        }
    }
 
    var body: some View {
     
        let dragGesture = DragGesture()
        .updating($dragState) { value, state, transaction in
            state = .dragging(translation: value.translation)
        }
        .onEnded { value in
            self.viewDragState.height += value.translation.height
            self.viewDragState.width += value.translation.width
        }
     
        return GeometryReader { geometry in
            ZStack(alignment: .top) {
                VStack(spacing: 0) {
                    ForEach(0..<2) {_ in
                        Text("X").frame( height: 60)
                        Divider()
                    }
                }
                Text("Meet with Test 2-4").frame(width: geometry.size.width, height: 60, alignment: .topLeading).background(Color.red)
                    .offset(self.translationOffset)
                .gesture(dragGesture)
            }
        }
    }
}

struct ContentView: View {
    var body: some View {
        HStack {
            DayView().background(Color.blue)
            DayView().background(Color.yellow)
            DayView().background(Color.green)
        }.padding(10).border(Color.red, width: 3)
    }
}


struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

Apparently that did not solve your issue ? Thanks to report what does not work or meet your need.