微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

SwiftUI 中的自定义注解 (MKMapView)

如何解决SwiftUI 中的自定义注解 (MKMapView)

我已经在 SwiftUI 中实现了一个 MKMapView,我正在显示一个注释列表(站点)以及用户的位置。 我想将点击功能添加到“停止销”,但我找不到任何有助于实现这一点的东西。

代码的问题在于它更改了用户位置 pin 的视图,最终崩溃并出现以下错误

2021-07-10 18:31:21.434538+0900 Bus Finder[5232:2086940] *** Terminating app due to uncaught exception 'NSGenericException',reason: '<Bus_Finder.Stops: 0x2816c4cc0> must implement title,or view (null) must have a non-nil detailCalloutAccessoryView when canShowCallout is YES on corresponding view <MKAnnotationView: 0x13137cd60; frame = (-20 -20; 40 40); opaque = NO; layer = <CALayer: 0x2832e9e20>>'
*** First throw call stack:
(0x196f2a754 0x1ab9f17a8 0x1a6566410 0x1a65655bc 0x1a656464c 0x1a65641d0 0x1982fd458 0x196ea522c 0x196ea4e28 0x196ea4278 0x196e9e02c 0x196e9d360 0x1ae4db734 0x199918584 0x19991ddf4 0x19ddf3370 0x19ddf32fc 0x19d8ebb6c 0x100eacf54 0x100eacff4 0x196b59cf8)
libc++abi: terminating with uncaught exception of type NSException
*** Terminating app due to uncaught exception 'NSGenericException',or view (null) must have a non-nil detailCalloutAccessoryView when canShowCallout is YES on corresponding view <MKAnnotationView: 0x13137cd60; frame = (-20 -20; 40 40); opaque = NO; layer = <CALayer: 0x2832e9e20>>'
terminating with uncaught exception of type NSException

我只想更改“停止销”的视图并添加点击功能。 我将停止列表传递给 MapView 出现。 Stops 结构位于末尾。

我的问题的视觉概念:

When commenting the viewFor annotation function

(注释viewFor注解函数时) 我想更改停止图钉的样式并向其添加点击功能,而不是用户的位置图钉。

When using the viewFor annotation function

当我使用 viewFor 注释函数(与本问题中的代码相同)时,用户位置视图发生变化,然后应用程序崩溃。

MapView 文件

// MARK: MapView
struct MapView: UIViewRepresentable {
    
    // MARK: Variables
    @Binding var stops: [Stops]
    @Binding var centerCoordinate: MKCoordinateRegion
    @Binding var action: Action
    
    // MARK: Action Lists
    enum Action {
        case idle
        case reset(coordinate: MKCoordinateRegion)
        case changeType(mapType: MKMapType)
    }
    
    // MARK: First Time Only
    func makeUIView(context: Context) -> MKMapView {
        let mapView = MKMapView()
        mapView.delegate = context.coordinator
        mapView.showsUserLocation = true
        mapView.userTrackingMode = .follow
        mapView.isUserInteractionEnabled = true
        mapView.centerCoordinate = self.centerCoordinate.center
        mapView.setRegion(self.centerCoordinate,animated: true)
        return mapView
    }
    
    // MARK: Updating UI
    func updateUIView(_ view: MKMapView,context: Context) {
        switch action {
        case .idle:
            break
        case .reset(let newCoordinate):
            view.delegate = nil
            
            dispatchQueue.main.async {
                self.centerCoordinate.center = newCoordinate.center
                self.action = .idle
                view.setRegion(self.centerCoordinate,animated: true)
                view.delegate = context.coordinator
            }
        case .changeType(let mapType):
            view.mapType = mapType
        }
        view.addAnnotations(stops)
    }
    
    // MARK: Setting Coordinator
    func makeCoordinator() -> Coordinator {
        Coordinator(self)
    }
    
    class Coordinator: NSObject,MKMapViewDelegate {
        var parent: MapView
        
        init(_ parent: MapView) {
            self.parent = parent
        }
        
        func mapViewDidChangeVisibleRegion(_ mapView: MKMapView) {
            parent.centerCoordinate.center = mapView.centerCoordinate
            
        }
        
        func mapView(_ mapView: MKMapView,viewFor annotation: MKAnnotation) -> MKAnnotationView? {
            let annotationView = MKAnnotationView(annotation: annotation,reuseIdentifier: "TESTING NOTE")
            annotationView.canShowCallout = true
            annotationView.image = UIImage(systemName: "location.circle")?.withTintColor(.systemGreen,renderingMode: .alwaysOriginal)
            let size = CGSize(width: 40,height: 40)
            annotationView.image = UIGraphicsImageRenderer(size:size).image {
                _ in annotationView.image!.draw(in:CGRect(origin:.zero,size:size))
            }
            return annotationView
        }
        
    }
}

Stops 结构文件

// MARK: StopPinPoint
final class Stops: NSObject,Codable,Identifiable,MKAnnotation {
    
    var id: String?
    var name: BusstopName
    var images: [String]?
    var landMarks: [String]?
    var coordinate: CLLocationCoordinate2D
    var prevNexStop: [String]?
    
    init(id: String?,name: BusstopName,images: [String]?,landMarks: [String]?,coordinates: CLLocationCoordinate2D,prevNextStop: [String]?) {
        self.id = id
        self.name = name
        self.coordinate = coordinates
        self.images = images
        self.landMarks = landMarks
        self.prevNexStop = prevNextStop
    }
    
    var location: CLLocation {
        return CLLocation(latitude: self.coordinate.latitude,longitude: self.coordinate.longitude)
    }
    
    func distance(to location: CLLocation) -> CLLocationdistance {
        return location.distance(from: self.location)
    }
}

如果有人能帮助我,我将不胜感激!我已经研究这个问题好几个星期了!

解决方法

所以基本上经过更多的搜索,我找到了答案。

为了不改变用户的位置 pin,我必须检查注释的类型,如果类型是 MKUserLocation,我应该返回 nil。

随后崩溃的原因是我必须使 Stops 结构确认为 MKPointAnnotation 并删除或覆盖坐标变量然后当我制作 Stops 列表时我可以简单地定义标题、副标题和坐标。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?