Is there something additional that needs to be specified for the Map to allow the MapFeatures and Markers to be selected?
Here's something to try, through you'll need to make some small modifications to handle your search results.
struct MapView: View {
@Environment(MapModel.self) private var mapModel
/// The `MapCameraPosition` describes how to position the map’s camera within the map.
@State private var mapCameraPosition: MapCameraPosition = .automatic
/// The currently selected map feature.
@State private var selection: MapSelection<MKMapItem>?
var body: some View {
@Bindable var mapModel = mapModel
Map(position: $mapCameraPosition, selection: $selection) {
UserAnnotation()
ForEach(mapModel.searchResults, id: \.self) { result in
/*
Display each search result as an annotation on the map using MapKit's default
annotation style, including iconography based on the map item's point-of-interest category.
The `tag` modifier enables selection of these items through the `selection` binding.
*/
Marker(item: result)
.tag(MapSelection(result))
}
/*
This selection accessory modifier allows people to tap on the annotations that the app adds to the map and get more detailed
information on the annotation, which displays as either a sheet or a callout according to the `style` parameter. Along with
the `selection` binding, this determines which annotation to display additional information for.
This modifier differs from the `mapFeatureSelectionAccessory(:_) modifier, which enables the same selection
behaviors on map features, such as points of interest that `Map` displays.
*/
.mapItemDetailSelectionAccessory(.automatic)
}
.mapStyle(.standard(pointsOfInterest: mapModel.searchConfiguration.pointOfInterestOptions.categories))
// Only allow selection for points of interest, and disable selection of other labels, like city names.
.mapFeatureSelectionDisabled { feature in
feature.kind != MapFeature.FeatureKind.pointOfInterest
}
/*
The selection accessory allows people to tap on map features and get more detailed information, which displays
as either a sheet or a callout according to the `style` parameter. Along with the `selection` binding, this determines
which feature to display additional information for.
This modifier differs from the `mapItemDetailSelectionAccessory(:_) modifier, which enables the same selection
behaviors on annotations that the app adds to `Map` for search results.
*/
.mapFeatureSelectionAccessory(.automatic)
.onMapCameraChange(frequency: .onEnd) { cameraContext in
// When the camera changes position, such as when a person moves or zooms the map, update
// the region the app uses for searching to reflect the changes to the visible map region.
mapModel.searchConfiguration.region = cameraContext.region
}
.onChange(of: mapModel.searchResults) {
// Adjust the map camera to make all of the annotations representing the search results visible.
mapCameraPosition = .automatic
}
.onChange(of: selection) { _, newSelection in
updateModelWithSelectedFeature(newSelection)
}
}
private func updateModelWithSelectedFeature(_ selection: MapSelection<MKMapItem>?) {
if let mapItem = selection?.value {
// The person has selected an annotation, such as a search result.
} else if let feature = selection?.feature {
// The person has selected a map feature, such as a point of interest. Because the map feature doesn't contain the
// details as an `MKMapItem`, request a map item for the feature.
Task {
let request = MKMapItemRequest(feature: feature)
var mapItem: MKMapItem? = nil
do {
mapItem = try await request.mapItem
mapModel.selectedMapItem = mapItem
} catch let error {
let logger = Logger(subsystem: Bundle.main.bundleIdentifier!, category: "Map Item Requests")
logger.error("Getting map item from map feature failed. Error: \(error.localizedDescription)")
}
}
} else {
}
}
}
— Ed Ford, DTS Engineer