SwiftUI DragGesture() get start location on screen

3.7k Views Asked by At

I want to make a view "swipeable", however this view only covers a small share of the whole screen. Doing:

var body: some View {
    
    ZStack {
        Text("ABC")
            .gesture(DragGesture().onChanged(onChanged))
    }
}

func onChanged(value: DragGesture.Value) {
    print(value.startLocation)
    print("onChanged", value.location)
}

Gives me relative values where the user has swiped - however, without knowing the exact location of the view, I'm unable to know where the user's touch is on the screen.

In other words, when the Text is in the center of the screen, going all the way to the right edge gives 200px. But let's say the Text moved to the left, then it would be almost 400. I tried putting another gesture on the ZStack to save the initial value, however it appears you can't have multiple gestures within each other.

How can I make the listener translate the values so the left edge is 0 and the right edge is displayWidth in px, regardless of where the Text is?

1

There are 1 best solutions below

0
On BEST ANSWER

You can make use of coordinate spaces, and use that with DragGesture.

Code:

struct ContentView: View {
    @State private var location: CGPoint = .zero

    var body: some View {
        VStack(spacing: 30) {
            Text("ABC")
                .background(Color.red)
                .gesture(
                    DragGesture(coordinateSpace: .named("screen")).onChanged(onChanged)
                )

            Text("Location: (\(location.x), \(location.y))")
        }
        .frame(maxWidth: .infinity, maxHeight: .infinity)
        .coordinateSpace(name: "screen")
    }

    private func onChanged(value: DragGesture.Value) {
        location = value.location
    }
}