Map
Map copied to clipboard
Detail callout accessory view
based on the work of @RomanPodymov
I'm honestly thinking whether this is the best approach for this - maybe something like a view modifier on that annotation would be more suitable, but we would also deviate from the existing API there - but then again, afaik detailCalloutAccessory is not supported by the SwiftUI wrapper from MapKit anyways
Hello @pauljohanneskraft Or you can keep a branch for "non-SwiftUI-API-features".
@RomanPodymov What do you think about a solution like this:
#if !os(watchOS)
import Foundation
import MapKit
import SwiftUI
private struct DetailCalloutAccessory<Annotation: MapAnnotation, Content: View>: MapAnnotation {
// MARK: Static Functions
static func registerView(on mapView: MKMapView) {
Annotation.registerView(on: mapView)
}
// MARK: Stored Properties
private let wrappedAnnotation: Annotation
private let content: () -> Content
// MARK: Computed Properties
var annotation: MKAnnotation {
wrappedAnnotation.annotation
}
// MARK: Initialization
init(_ annotation: Annotation, @ViewBuilder content: @escaping () -> Content) {
self.wrappedAnnotation = annotation
self.content = content
}
// MARK: Methods
func view(for mapView: MKMapView) -> MKAnnotationView? {
guard let view = wrappedAnnotation.view(for: mapView) else {
return nil
}
if Content.self != EmptyView.self {
view.canShowCallout = true
view.detailCalloutAccessoryView = NativeHostingController(rootView: content()).view
} else {
view.canShowCallout = false
view.detailCalloutAccessoryView = nil
}
return view
}
}
extension MapAnnotation {
public func detailCalloutAccessory<Content: View>(@ViewBuilder content: @escaping () -> Content) -> some MapAnnotation {
DetailCalloutAccessory(self, content: content)
}
}
#endif
It could then be used on any MapAnnotation using the following construct:
ViewMapAnnotation(...) {
AnnotationContent()
}
.detailCalloutAccessory {
DetailCalloutAccessoryContent()
}
Hello @pauljohanneskraft Looks great. I don't have that much experience with SwiftUI, so I trust you.
For what it's worth, it doesn't look like iOS 17 adds callouts to the SwiftUI Map component based on the initial beta documentation at https://developer.apple.com/documentation/mapkit/mapkit_for_swiftui
The proposed solution at https://github.com/pauljohanneskraft/Map/pull/46#issuecomment-1529020296 looks reasonable to me.
Hello @darronschall If it is similar to iOS 17 SwiftUI Map API we can try this way.