在 SwiftUI 中选择注释时显示叠加视图
Display overlay view when selecting annotation in SwiftUI
我正在使用 UIRepresentable 在地图上显示注释,并希望在点击选定的图钉时能够显示视图。
我以前使用 Map()
所以能够使用 .onTapGesture
作为注释,但现在注释是从 UIKit 制作的,我如何将所选项目传递到主视图?
我以前的工作:
var body: some View {
ZStack {
Map(region: $region, annotationItems: $model.locations) { location in
MapPin(coordinate: location.coord)
.onTapGesture {
modelData.selectedLocation = location
modelData.isShowingDetail = true
}
}
if modelData.isShowingDetail {
DetailView(
isShowingDetail: $modelData.isShowingDetail,
location: modelData.selectedLocation!
)
}
}
}
现在我有了 UIViewRepresentable:
struct UIMapView: UIViewRepresentable {
// default setup - coordinator, makeUI, updateUI
class Coordinator: NSObject, MKMapViewDelegate {
func mapView(_ mapView: MKMapView, didSelect view: MKAnnotationView) {
// how to trigger the overlay??
}
}
}
任何帮助将不胜感激,因为我非常坚持这一点:)
在您的 class Coordinator: NSObject, MKMapViewDelegate {...}
中,您可以访问以下功能:
func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer {
...
}
func mapView(_ mapView: MKMapView, annotationView view: MKAnnotationView, calloutAccessoryControlTapped control: UIControl) {
...
}
使用这些(和其他)来做你想做的事。
您想知道在 SwiftUI 视图中选择的注释。所以你必须把它存放在某个地方。声明一个 @State
:
struct ContentView: View {
let locations: [MKAnnotation]
@State private var selectedLocation: MKAnnotation?
var body: some View {
// ... //
}
}
现在在您的包装器 (UIViewRepresentable
) 中,您必须与此 MKAnnotation?
进行绑定:
struct MapView: UIViewRepresentable {
@Binding var selectedLocation: MKAnnotation? // HERE
let annotations: [MKAnnotation]
func makeUIView(context: Context) -> MKMapView {
let mapView = MKMapView()
mapView.region = // .... //
mapView.addAnnotations(annotations)
mapView.delegate = context.coordinator
return mapView
}
func updateUIView(_ view: MKMapView, context: Context) {
// .... //
}
现在您应该可以在您的委托(协调器)中访问此变量。为此,您必须将 UIViewRepresentable 传递给协调器:
func makeCoordinator() -> Coordinator {
Coordinator(self)
}
class Coordinator: NSObject, MKMapViewDelegate {
var parent: MapView
init(_ parent: MapView) {
self.parent = parent
}
最后,在 func mapView(_ mapView: MKMapView, didSelect view: MKAnnotationView)
中,您可以在 parent.selectedLocation
中复制 MKAnnotation。
使用 @Binding
这个 MKAnnotation
现在可以在您的父视图 (ContentView
) 中访问。您可以在 DetailView
.
中显示其属性
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
// ... //
}
func mapView(_ mapView: MKMapView, didSelect view: MKAnnotationView) {
parent.selectedLocation = view.annotation
}
}
}
例如:
struct ContentView: View {
let locations: [MKAnnotation]
@State private var selectedLocation: MKAnnotation?
var body: some View {
VStack {
Text("\(selectedLocation?.coordinate.latitude ?? 0)")
// Don't forget the Binding : $selectedLocation
MapView(selectedLocation: $selectedLocation, annotations: locations)
}
}
}
我正在使用 UIRepresentable 在地图上显示注释,并希望在点击选定的图钉时能够显示视图。
我以前使用 Map()
所以能够使用 .onTapGesture
作为注释,但现在注释是从 UIKit 制作的,我如何将所选项目传递到主视图?
我以前的工作:
var body: some View {
ZStack {
Map(region: $region, annotationItems: $model.locations) { location in
MapPin(coordinate: location.coord)
.onTapGesture {
modelData.selectedLocation = location
modelData.isShowingDetail = true
}
}
if modelData.isShowingDetail {
DetailView(
isShowingDetail: $modelData.isShowingDetail,
location: modelData.selectedLocation!
)
}
}
}
现在我有了 UIViewRepresentable:
struct UIMapView: UIViewRepresentable {
// default setup - coordinator, makeUI, updateUI
class Coordinator: NSObject, MKMapViewDelegate {
func mapView(_ mapView: MKMapView, didSelect view: MKAnnotationView) {
// how to trigger the overlay??
}
}
}
任何帮助将不胜感激,因为我非常坚持这一点:)
在您的 class Coordinator: NSObject, MKMapViewDelegate {...}
中,您可以访问以下功能:
func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer {
...
}
func mapView(_ mapView: MKMapView, annotationView view: MKAnnotationView, calloutAccessoryControlTapped control: UIControl) {
...
}
使用这些(和其他)来做你想做的事。
您想知道在 SwiftUI 视图中选择的注释。所以你必须把它存放在某个地方。声明一个 @State
:
struct ContentView: View {
let locations: [MKAnnotation]
@State private var selectedLocation: MKAnnotation?
var body: some View {
// ... //
}
}
现在在您的包装器 (UIViewRepresentable
) 中,您必须与此 MKAnnotation?
进行绑定:
struct MapView: UIViewRepresentable {
@Binding var selectedLocation: MKAnnotation? // HERE
let annotations: [MKAnnotation]
func makeUIView(context: Context) -> MKMapView {
let mapView = MKMapView()
mapView.region = // .... //
mapView.addAnnotations(annotations)
mapView.delegate = context.coordinator
return mapView
}
func updateUIView(_ view: MKMapView, context: Context) {
// .... //
}
现在您应该可以在您的委托(协调器)中访问此变量。为此,您必须将 UIViewRepresentable 传递给协调器:
func makeCoordinator() -> Coordinator {
Coordinator(self)
}
class Coordinator: NSObject, MKMapViewDelegate {
var parent: MapView
init(_ parent: MapView) {
self.parent = parent
}
最后,在 func mapView(_ mapView: MKMapView, didSelect view: MKAnnotationView)
中,您可以在 parent.selectedLocation
中复制 MKAnnotation。
使用 @Binding
这个 MKAnnotation
现在可以在您的父视图 (ContentView
) 中访问。您可以在 DetailView
.
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
// ... //
}
func mapView(_ mapView: MKMapView, didSelect view: MKAnnotationView) {
parent.selectedLocation = view.annotation
}
}
}
例如:
struct ContentView: View {
let locations: [MKAnnotation]
@State private var selectedLocation: MKAnnotation?
var body: some View {
VStack {
Text("\(selectedLocation?.coordinate.latitude ?? 0)")
// Don't forget the Binding : $selectedLocation
MapView(selectedLocation: $selectedLocation, annotations: locations)
}
}
}