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