简体   繁体   English

如何从 mapkit 注释导航 - SwiftUI/Xcode 11

[英]How to navigate from mapkit annotation - SwiftUI/Xcode 11

I'm using MapKit in Xcode 11.1 with SwiftUI to show a map with annotations.我在 Xcode 11.1 和 SwiftUI 中使用 MapKit 来显示带有注释的 map。 The annotations have a callout which shows the title, and a button on the rightCalloutAccessoryView.注释有一个显示标题的标注,以及右边的CalloutAccessoryView 上的一个按钮。 I want to be able to navigate to another view when the user clicks the rightCalloutAccessoryView button.当用户单击 rightCalloutAccessoryView 按钮时,我希望能够导航到另一个视图。

A NavigationLink within the calloutAccessoryControlTapped function isn't working. calloutAccessoryControlTapped function 中的 NavigationLink 不起作用。 How should this be done in SwiftUI?在 SwiftUI 中应该怎么做? Any help is much appreciated!任何帮助深表感谢!

func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {

var annotationView = mapView.dequeueReusableAnnotationView(withIdentifier: "AnnotationView")

if annotationView == nil {
    annotationView = MKAnnotationView(annotation: annotation, reuseIdentifier: "AnnotationView")
}

let whiteImage = UIImage(named: "white")

annotationView!.image = whiteImage
      annotationView?.isEnabled = true
      annotationView?.canShowCallout = true
      annotationView?.centerOffset = CGPoint(x: 0, y: -23)


let button = UIButton(type: .detailDisclosure)
annotationView?.rightCalloutAccessoryView = button

return annotationView

} }

func mapView(_ mapView: MKMapView, annotationView view: MKAnnotationView, calloutAccessoryControlTapped control: UIControl) {

@State var tapped = true
//ERROR: Property wrappers are not yet supported on local properties

NavigationLink(destination: DetailView(), isActive: $tapped) {EmptyView()}
//ERROR: Use of unrecognized identifier '$tapped'

} }

Hope it's not too late but I ran into the same issue.希望现在还不算晚,但我遇到了同样的问题。 I figured out a workaround by using NavigationLink with isActive: .我想出了一个解决方法,将 NavigationLink 与isActive:一起使用。 First create @State variables in where you include your SwiftUI MapView like:首先在包含 SwiftUI MapView 的位置创建@State变量,例如:

@State var isActive: Bool = false
@State var selectedAnnotation: MKAnnotation?

Then group a NavigationLink with your SwiftUI MapView like this:然后将 NavigationLink 与您的 SwiftUI MapView 分组,如下所示:

Group {
    NavigationLink(destination: [relate your selectedAnnotation to your destination view], isActive: self.$isActive) {
        EmptyView()
    }
    MapView(annotations: getAnnotations(), isClicked: self.$isActive, selectedAnnotation: self.$selectedAnnotation)
}

Finally inside your Coordinator/MKMapViewDelegate最后在你的 Coordinator/MKMapViewDelegate

func mapView(_ mapView: MKMapView, annotationView view: MKAnnotationView, calloutAccessoryControlTapped control: UIControl) {}

you would want to do something like:你会想做这样的事情:

self.view.isClicked = true
self.view.selectedAnnotation = view.annotation

Note that the view in view.annotation refers to annotationView view: MKAnnotationView while self.view refers to var view: MapView in请注意, view.annotation中的view是指annotationView view: MKAnnotationViewself.view是指var view: MapView

class Coordinator: NSObject, MKMapViewDelegate {
    var view: MapView

    init(_ control: MapView) {
        self.view = control
    }

    func mapView(_ mapView: MKMapView, viewFor
            annotation: MKAnnotation) -> MKAnnotationView? {}

    func mapView(_ mapView: MKMapView, annotationView view: MKAnnotationView, calloutAccessoryControlTapped control: UIControl) {}
    ...
}

There's probably a better way to do this but this works!可能有更好的方法来做到这一点,但这有效!

Note: I created MapView that conforms to UIViewRepresentable.注意:我创建了符合 UIViewRepresentable 的MapView

There is no mapView(...) API to do this.没有mapView(...) API 可以做到这一点。

What you do is something like你所做的就像

button.addTarget(self, action: #selector(self.buttonAction(_:)), for: .touchUpInside)

to get the tap from your button.从您的按钮获得点击。

This is a good API design from Apple, since it gives you the freedom to use arbitrary controls, including container views containing several arbitrary controls.这是来自 Apple 的一个很好的 API 设计,因为它让您可以自由使用任意控件,包括包含多个任意控件的容器视图。

Think of this problem as "how do I use a UIButton programmatically?".将此问题视为“我如何以编程方式使用 UIButton?”。 The fact that the UIButton is used inside MapKit is not very relevant.在 MapKit 中使用UIButton的事实并不是很相关。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM