Map
Map copied to clipboard
Share knowledge on maintaining SwiftUI frames
These changes achieve 2 main things:
- The SwiftUI view's correctly follow the
MKMapAnnotationView
's frame around on the map. This fixes usingonTapGesture
directly on the SwiftUI view that represents the annotation - The hosted SwiftUI is now updated (when Map is re-evaluated, which means when
coordinateRegion
changes, the annotations will be re-calculated. This allows hosting views that have inputs.
The result can be something like this:
https://user-images.githubusercontent.com/8225090/224500047-a4eb805e-f491-4303-a42c-8f66b1a13df1.mov
struct AnnotationPinView: View {
let isSelected: Bool
var body: some View {
Image(systemName: "mappin")
.renderingMode(.template)
.aspectRatio(contentMode: .fit)
.frame(width: 30, height: 30)
.background(.green)
.shadow(color: .black.opacity(0.5), radius: 0.9, x: 0.0, y: 2.0)
.clipShape(Circle())
// Note: Scale effect does not change intrinsicContentSize on the hosting view
.scaleEffect(isSelected ? 1.5 : 1, anchor: .bottom)
.animation(.interpolatingSpring(stiffness: 300, damping: 15, initialVelocity: 30), value: isSelected)
.foregroundColor(isSelected ? .yellow : .blue)
}
}
Map(
coordinateRegion: $coordinateRegion,
annotationItems: items,
annotationContent: { itemModel in
ViewMapAnnotation(
coordinate: itemModel.coordinate,
anchorPoint: CGPoint(x: 0.5, y: 1.0)
) {
AnnotationPinView(isSelected: currentItem.id == itemModel.id)
.onTapGesture {
currentItem = itemModel
}
}
}
)
.ignoresSafeArea()