Swift 自定义注释视图的奇怪行为

Swift 自定义注释视图的奇怪行为,swift,mapkit,Swift,Mapkit,我在SwiftUI和Storyboard中构建了相同的代码,我也遇到了同样的奇怪问题 每当我运行并转到后台,再回到前台时,自定义视图都会丢失。 每当我放大拖动到远处(比如10公里),我也会丢失非图片固定销,例如“铅笔” 我不确定哪里出了问题,除了可能需要根据注释视图“type”(带有给定图片,带有文本…)分离我的pin,并在此基础上设置一个不同的重用标识符,但这听起来很奇怪,因为我实际上没有创建任何新的内容(只设置baseMKAnnotationView类的属性) 使用UIKit版本作为参考:

我在SwiftUI和Storyboard中构建了相同的代码,我也遇到了同样的奇怪问题

每当我运行并转到后台,再回到前台时,自定义视图都会丢失。 每当我放大拖动到远处(比如10公里),我也会丢失非图片固定销,例如“铅笔”

我不确定哪里出了问题,除了可能需要根据注释视图“type”(带有给定图片,带有文本…)分离我的pin,并在此基础上设置一个不同的重用标识符,但这听起来很奇怪,因为我实际上没有创建任何新的内容(只设置base
MKAnnotationView
类的属性)

使用UIKit版本作为参考:

import UIKit
import MapKit

class MapViewController: UIViewController {
    @IBOutlet weak var mapView: MKMapView!

    let cityMapManager = CityMapManager()
    let cityMapViewDelegate = CityMapViewDelegate()

    let places: [Place] = [Place(name: "Cathedral", location: .init(latitude: 50.640364, longitude: 3.062058))]

    override func viewDidLoad() {
        super.viewDidLoad()

        mapView.setRegion(MKCoordinateRegion(center: CLLocationCoordinate2D(latitude: 50.640364, longitude: 3.062058), latitudinalMeters: 500.0, longitudinalMeters: 500.0), animated: false)
        mapView.showsUserLocation = true
        mapView.showsScale = true
        mapView.delegate = cityMapViewDelegate
        annotateLocalPOI(map: mapView)
    }

    private func annotateLocalPOI(map: MKMapView) {

        var annotation = MKPointAnnotation()
        annotation.title = "Red Pin"
        annotation.subtitle = "I'm a pin and I'm red. Maybe, or not."
        annotation.coordinate = CLLocationCoordinate2D(latitude: 50.64, longitude: 3.06)
        // add the annotation to the map (will use red pin, mapView:viewFor: allows changing the display)
        map.addAnnotation(annotation)
        annotation = MKPointAnnotation()
        annotation.title = "Pencil"
        annotation.subtitle = "Will not display"
        annotation.coordinate = CLLocationCoordinate2D(latitude: 50.642, longitude: 3.059)
        map.addAnnotation(annotation)
    }    
}

struct Place: Identifiable {
    let id: UUID = UUID()
    let name: String
    let location: CLLocationCoordinate2D
}

class CityMapViewDelegate: NSObject, MKMapViewDelegate {

    func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
        guard annotation is MKPointAnnotation else { return nil }

        let identifier = "Annotation"
        var annotationView = mapView.dequeueReusableAnnotationView(withIdentifier: identifier)

        if annotationView == nil {
            annotationView = MKPinAnnotationView(annotation: annotation, reuseIdentifier: identifier)
            annotationView!.canShowCallout = true
            if annotation.title == "Red Pin" {
                let pinImage = UIImage(systemName: "timelapse")
                annotationView?.image = pinImage
            }
            if annotation.title == "Pencil" {
                // this overrules any subtitle available
                annotationView?.detailCalloutAccessoryView = UIImageView(image: UIImage(systemName: "pencil"))
            }
        } else {
            // reset
            annotationView?.detailCalloutAccessoryView = nil
            annotationView?.image = nil
            // set it up again
            annotationView?.annotation = annotation
            if annotation.title == "Red Pin" {
                let pinImage = UIImage(systemName: "timelapse")
                annotationView?.image = pinImage
            }
            if annotation.title == "Pencil" {
                // this overrules any subtitle available
                annotationView?.detailCalloutAccessoryView = UIImageView(image: UIImage(systemName: "pencil"))
            }
        }
        return annotationView
    }
}

class CityLocationManagerDelegate: NSObject, CLLocationManagerDelegate {

    var locationStatus = "Status not determined"
    var locationFixFound = false

    func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {

        // We've (at least once) gone under a certain minimum accuracy required to consider we have a "fix"
        // we could use that to reflect that information on the UI (color, shape...)
        if !locationFixFound {
            for location in locations {
                if location.horizontalAccuracy < 25.0 {
                    locationFixFound = true
            }
        }

        }
    }

    func locationManager(_ manager: CLLocationManager,
                            didFailWithError error: Error) {
        manager.stopUpdatingLocation()
        print("Location manager stopped due to error: \(error)")
    }

    func locationManager(_ manager: CLLocationManager,
                         didChangeAuthorization status: CLAuthorizationStatus) {
        print("Authorization Status changed")
        var shouldRequestLocationUpdates = false

        switch status {
        case CLAuthorizationStatus.restricted:
            locationStatus = "Restricted Access to location"
        case CLAuthorizationStatus.denied:
            locationStatus = "User denied access to location"
        case CLAuthorizationStatus.notDetermined:
            locationStatus = "Status not determined"
        default:
            locationStatus = "Allowed to location Access"
            shouldRequestLocationUpdates = true
        }

        if (shouldRequestLocationUpdates == true) {
            NSLog("Location to Allowed")
            // Start location services
            manager.startUpdatingLocation()
        } else {
            NSLog("Denied access: \(locationStatus)")
        }
    }
}

struct CityMapManager {

    let locationDelegate: CLLocationManagerDelegate
    let locationManager: CLLocationManager

    init() {
        locationDelegate = CityLocationManagerDelegate()
        locationManager = CLLocationManager()
        locationManager.delegate = locationDelegate
        locationManager.desiredAccuracy = kCLLocationAccuracyBest
        locationManager.requestWhenInUseAuthorization()
        locationManager.requestAlwaysAuthorization()
    }
}
导入UIKit
导入地图套件
类MapViewController:UIViewController{
@ibvar映射视图:MKMapView!
让cityMapManager=cityMapManager()
设cityMapViewDelegate=cityMapViewDelegate()
let places:[地点]=[地点(名称:“大教堂”,位置:.init(纬度:50.640364,经度:3.062058))]
重写func viewDidLoad(){
super.viewDidLoad()
地图视图。设置区域(MKCoordinateRegion(中心:CLLocationCoordinate2D(纬度:50.640364,经度:3.062058),纬度计:500.0,经度计:500.0),动画:false)
mapView.showsUserLocation=true
mapView.showscale=true
mapView.delegate=cityMapViewDelegate
注释LocalPOI(映射:mapView)
}
专用func注释本地POI(映射:MKMapView){
var annotation=MKPointAnnotation()
annotation.title=“红色Pin”
annotation.subtitle=“我是一个大头针,我是红色的。也许吧,也许不是。”
annotation.coordinate=CLLocationCoordinate2D(纬度:50.64,经度:3.06)
//将注释添加到地图(将使用红色pin,mapView:viewFor:允许更改显示)
map.addAnnotation(注释)
annotation=MKPointAnnotation()
annotation.title=“铅笔”
annotation.subtitle=“将不显示”
annotation.coordinate=CLLocationCoordinate2D(纬度:50.642,经度:3.059)
map.addAnnotation(注释)
}    
}
结构位置:可识别{
let id:UUID=UUID()
let name:String
let位置:CLLocationCoordinate2D
}
类CityMapViewDelegate:NSObject,MKMapViewDelegate{
func mapView(uMapView:MKMapView,viewFor annotation:MKAnnotation)->MKAnnotationView{
guard批注为MKPointAnnotation else{return nil}
让标识符=“注释”
var annotationView=mapView.dequeueReusableAnnotationView(带标识符:标识符)
如果annotationView==nil{
annotationView=MKPinAnnotationView(注释:注释,重用标识符:标识符)
annotationView!.canShowCallout=true
如果annotation.title==“红色Pin”{
让pinImage=UIImage(系统名称:“timelapse”)
注释视图?.image=pinImage
}
如果annotation.title==“铅笔”{
//这否决了任何可用的字幕
annotationView?.detailCalloutAccessoryView=UIImageView(图像:UIImage(系统名称:“铅笔”))
}
}否则{
//重置
annotationView?.detailCalloutAccessoryView=nil
注释视图?.image=nil
//重新设置
annotationView?.annotation=注释
如果annotation.title==“红色Pin”{
让pinImage=UIImage(系统名称:“timelapse”)
注释视图?.image=pinImage
}
如果annotation.title==“铅笔”{
//这否决了任何可用的字幕
annotationView?.detailCalloutAccessoryView=UIImageView(图像:UIImage(系统名称:“铅笔”))
}
}
返回注释视图
}
}
类CityLocationManagerDelegate:NSObject,CLLocationManagerDelegate{
var locationStatus=“状态未确定”
var locationFixFound=false
func locationManager(manager:CLLocationManager,didUpdateLocations位置:[CLLocation]){
我们至少已经有过一次,认为我们有一个“固定”需要一定的最小精确度。
//我们可以使用它在UI上反映这些信息(颜色、形状…)
如果!找到locationFixFound{
对于位置中的位置{
如果位置水平精度<25.0{
locationFixFound=true
}
}
}
}
func locationManager(uManager:CLLocationManager,
DIDFail(错误:错误){
manager.stopUpdateLocation()
打印(“位置管理器因错误而停止:\(错误)”)
}
func locationManager(uManager:CLLocationManager,
didChangeAuthorization状态:CLAuthorizationStatus){
打印(“授权状态已更改”)
var shouldRequestLocationUpdates=false
开关状态{
案例授权状态。受限:
locationStatus=“对位置的访问受限”
案例授权状态。拒绝:
locationStatus=“用户拒绝访问位置”
案例授权状态。未确定:
locationStatus=“状态未确定”
违约:
locationStatus=“允许对位置进行访问”
shouldRequestLocationUpdates=true
}
if(shouldRequestLocationUpdates==true){
NSLog(“允许的位置”)
//启动定位服务
经理:startUpdatingLocation()
}否则{
NSLog(“拒绝访问:\(locationStatus)”)
}
}
}
结构CityMapManager{
让locationDelegate:CLLocationManagerDelegate
让locationManager:CLLocationManager
init(){
locationDelegate=CityLocationManagerDelegate()
locationManager=CLLocationManager()
定位员