`onTapGesture` not triggered on `Map` views

When building with iOS 26 SDK beta 5 (23A5308f), onTapGesture is no longer being triggered on Map views. This appears to be a regression in beta 5 specifically, as this issue was not present in beta 4.

How to reproduce

Code

The following code demonstrates the issue, as seen in the videos below.

import MapKit
import SwiftUI

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

  var body: some View {
    Map()
      .onTapGesture { location in
        self.location = location
      }
      .safeAreaInset(edge: .bottom) {
        VStack(alignment: .center) {
          Text("iOS \(UIDevice.current.systemVersion)")
            .font(.largeTitle)

          Text("Tapped Location")
          Text("\(location.x), \(location.y)")
        }
        .frame(maxWidth: .infinity, alignment: .center)
        .background(.background)
      }
  }
}

Demo

The gifs below show the behavior in iOS 18.5 (in which the tap gestures are recognized and tapped coordinate is displayed in the safe area inset) and iOS 26 beta 5 (in which the tap gestures have no effect):

iOS 18iOS 26

Next steps?

Is there a recommended workaround for this issue?

Answered by jasonrudolph in 855111022

Thanks so much for that suggestion, @DTS Engineer!

That approach does indeed fire the callback for a tap. But in my particular case, I need the screen coordinate of the tap, and I don't see a way to get that using TapGesture().onEnded {}.

However, I found that SpatialTapGesture does provide the screen coordinate of the tap.

Here's what this workaround looks like applied to the code sample from the OP:

import MapKit
import SwiftUI

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

  var body: some View {
    Map()
      .simultaneousGesture(SpatialTapGesture()
        .onEnded { event in
          self.location = event.location
        }
      ).safeAreaInset(edge: .bottom) {
        VStack(alignment: .center) {
          Text("iOS \(UIDevice.current.systemVersion)")
            .font(.largeTitle)

          Text("Tapped Location")
          Text("\(location.x), \(location.y)")
        }
        .frame(maxWidth: .infinity, alignment: .center)
        .background(.background)
      }
  }
}

That seems to work well in my testing!

I'll adopt this workaround for now. Thanks for your help!


Docs:

Still not fixed in RC, will proceed with the workaround for initial iOS 26 support release.

This issue is noted in the iOS 26 Release Notes (search for FB19394663), so yes, you'll need to keep using the workarounds in this thread for now.

— Ed Ford,  DTS Engineer

For those having to deal with that bug and in need to get location for the tap, I've used the answer here https://stackoverflow.com/questions/56513942/how-to-detect-a-tap-gesture-location-in-swiftui with a slight modification :

import SwiftUI

struct ClickGesture: Gesture {
    let count: Int
    let coordinateSpace: CoordinateSpace
    
    typealias Value = SimultaneousGesture<TapGesture, DragGesture>.Value
    
    init(count: Int = 1, coordinateSpace: CoordinateSpace = .local) {
        precondition(count > 0, "Count must be greater than or equal to 1.")
        self.count = count
        self.coordinateSpace = coordinateSpace
    }
    
    var body: SimultaneousGesture<TapGesture, DragGesture> {
        SimultaneousGesture(
            TapGesture(count: count),
            DragGesture(minimumDistance: 0, coordinateSpace: coordinateSpace)
        )
    }
    
    func onEnded(perform action: @escaping (CGPoint) -> Void) -> _EndedGesture<ClickGesture> {
        self.onEnded { (value: Value) -> Void in
            guard value.first != nil else { return }
            guard let location = value.second?.startLocation else { return }
            guard let endLocation = value.second?.location else { return }
            guard ((location.x-1)...(location.x+1)).contains(endLocation.x),
                  ((location.y-1)...(location.y+1)).contains(endLocation.y) else {
                return
            }
            action(location)
        }
    }
}

extension View {
    func onClickGesture(
        count: Int,
        coordinateSpace: CoordinateSpace = .local,
        perform action: @escaping (CGPoint) -> Void
    ) -> some View {
        simultaneousGesture(ClickGesture(count: count, coordinateSpace: coordinateSpace)
            .onEnded(perform: action)
        )
    }
    
    func onClickGesture(
        count: Int,
        perform action: @escaping (CGPoint) -> Void
    ) -> some View {
        onClickGesture(count: count, coordinateSpace: .local, perform: action)
    }
    
    func onClickGesture(
        perform action: @escaping (CGPoint) -> Void
    ) -> some View {
        onClickGesture(count: 1, coordinateSpace: .local, perform: action)
    }
}
&#96;onTapGesture&#96; not triggered on &#96;Map&#96; views
 
 
Q