SwiftUI - how to get coordinate/position of clicked Button

You can use a DragGesture recogniser with a minimum drag distance of 0, which provides you the location info. However, if you combine the DragGesture with your button, the drag gesture won't be triggered on normal clicks of the button. It will only be triggered when the drag ends outside of the button.

You can get rid of the button completely, but of course then you lose the default button styling.

The view would look like this in that case:

struct MyView: View {

    @State var xPos: CGFloat = 0

    var body: some View {
        GeometryReader { geometry in
            HStack {
                Text("Sausages: \(self.xPos)")
            }
        }.gesture(DragGesture(minimumDistance: 0, coordinateSpace: .global).onEnded { dragGesture in
            self.xPos = dragGesture.location.x
        })
    }
}

The coordinateSpace parameter specifies if you want the touch position in .local or .global space. In the local space, the position is relative to the view that you've attached the gesture to. For example, if I had a Text view in the middle of the screen, my local y position would be almost 0, whereas my global y would be half of the screen height.

This tripped me up a bit, but this example shows the idea:

struct MyView2: View {

    @State var localY: CGFloat = 0
    @State var globalY: CGFloat = 0

    var body: some View {
        VStack {
            Text("local y: \(self.localY)")
                .gesture(DragGesture(minimumDistance: 0, coordinateSpace: .local).onEnded { dragGesture in
                    self.localY = dragGesture.location.y
                })

            Text("global y: \(self.globalY)")
                .gesture(DragGesture(minimumDistance: 0, coordinateSpace: .global).onEnded { dragGesture in
                    self.globalY = dragGesture.location.y
                })
        }
    }
}

Tags:

Swift

Swiftui