问题描述
我已经在 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
结构位于末尾。
我的问题的视觉概念:
(注释viewFor注解函数时) 我想更改停止图钉的样式并向其添加点击功能,而不是用户的位置图钉。
当我使用 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
列表时我可以简单地定义标题、副标题和坐标。