在 Swift 中使用 calloutAccessoryControlTapped 方法时,UIAlertController 视图未出现在地图上

问题描述

我正在创建我的第一个 IOS 应用程序,并且很难理解为什么 CalloutAccessoryControlTapped Control 功能不起作用。

“信息”按钮出现在注释上,但当用户点击“信息”按钮时,没有任何反应。在此处查看屏幕截图:Screenshot of Annotation

我在视图控制器中创建了一个函数来添加标注附件视图,并怀疑该函数有问题。

任何帮助将不胜感激!

功能如下:

func mapView(_ mapView: MKMapView,annotationView view: MKAnnotationView,calloutAccessoryControlTapped control: UIControl) {
               let annotation = view.annotation as? Fire
               let status = "Fire Status: Active"
               let distance = "Fire Location: 25 miles away"
               let ac = UIAlertController(title: status,message: distance,preferredStyle: .alert)
               ac.addAction(UIAlertAction(title: "Close",style: .default))
            self.present(ac,animated: true,completion: nil)
               }

这是我的视图控制器中的代码——2021 年 4 月 20 日更新:

import MapKit
import UIKit
import CoreLocation

class FireMapViewController: UIViewController,CLLocationManagerDelegate {

    @IBOutlet weak var FireMapView: MKMapView!
    
    let mapView = MKMapView()
    var locationManager = CLLocationManager()
    
    var lat = Double()
    var lon = Double()
    var fires: [Fire] = []
    
    override func viewDidLoad() {
        super.viewDidLoad()
        setupMapView()
        checkLocationServices()
        mapView.register(FireMarkerView.self,forAnnotationViewWithReuseIdentifier:
            MKMapViewDefaultAnnotationViewReuseIdentifier)
        
       
    //Initiate URL Session to get Fire data and add Fire data to the Map Annotations
        if let url = URL(string: "https://services3.arcgis.com/T4QMspbfLg3qTGWY/arcgis/rest/services/Active_Fires/FeatureServer/0/query?outFields=*&where=1%3D1&f=geojson") {
              
            URLSession.shared.dataTask(with: url) {data,response,error in
                    if let data = data {
                       do {
                           let features = try MKGeoJSONDecoder().decode(data)
                               .compactMap { $0 as? MKGeoJSONFeature }
                             let validWorks = features.compactMap(Fire.init)
                        self.fires.append(contentsOf: validWorks)
                              DispatchQueue.main.async {
                                self.mapView.addAnnotations(self.fires)
                              }
                                 }
                       catch let error {
                                    print(error)
                       }
                    
                        

                    }
                 }.resume()
        }
   
    }
    
    
    func setupMapView() {
        view.addSubview(mapView)
        mapView.translatesAutoresizingMaskIntoConstraints = false
        mapView.topAnchor.constraint(equalTo: view.topAnchor).isActive = true
        mapView.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true
        mapView.rightAnchor.constraint(equalTo: view.safeAreaLayoutGuide.rightAnchor).isActive = true
        mapView.leftAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leftAnchor).isActive = true
    }
    
   
    func checkLocationServices() {
        if CLLocationManager.locationServicesEnabled() {
            setupLocationManager()
            locationManagerDidChangeAuthorization(locationManager)
        } else {
            // the user didn't turn it on
        }
    }

//Get the current location permissions for User

func locationManagerDidChangeAuthorization(_ manager: CLLocationManager) {

    switch manager.authorizationStatus {
        case .authorizedAlways,.authorizedWhenInUse:
            mapView.showsUserLocation = true
            followUserLocation()
            locationManager.startUpdatingLocation()
            break
        case .notDetermined,.denied,.restricted:
            locationManager.requestWhenInUseAuthorization()
            break
        default:
            break
    }
    
    switch manager.accuracyAuthorization {
        case .fullAccuracy:
            break
        case .reducedAccuracy:
            break
        default:
            break
    }
}
    
    func setupLocationManager() {
        locationManager.delegate = self
        locationManager.desiredAccuracy = kCLLocationAccuracyBest
    }
    
    func locationManager(_ manager: CLLocationManager,didUpdateLocations locations: [CLLocation]) {
        guard let location = locations.last else { return }
        let region = MKCoordinateRegion.init(center: location.coordinate,latitudinalMeters:  160934,longitudinalMeters:  160934)
        mapView.setRegion(region,animated: true)
        print("Fire Map User Location on Map:",location.coordinate)
        
// Call stopUpdatingLocation() to stop listening for location updates,// other wise this function will be called every time when user location changes.
// Need a solution for this.
        manager.stopUpdatingLocation()
    }
    
    func followUserLocation() {
        if let location = locationManager.location?.coordinate {
            let region = MKCoordinateRegion.init(center: location,latitudinalMeters: 4000,longitudinalMeters: 4000)
            mapView.setRegion(region,animated: true)
        }
    }
    
    func locationManager(_ manager: CLLocationManager,didChangeAuthorization status: CLAuthorizationStatus) {
        locationManagerDidChangeAuthorization(locationManager)
    }
    


//Function to display additional Fire data after User selects the Callout Info button on the Annotation

      func mapView(_ mapView: MKMapView,calloutAccessoryControlTapped control: UIControl) {
              let annotation = view.annotation as? Fire
            print("callout Accessory Tapped!")
            let status = "Fire Status: Active"
              let distance = "Fire Location: 25 miles away"
              let ac = UIAlertController(title: status,preferredStyle: .alert)
              ac.addAction(UIAlertAction(title: "Close",style: .default))
           self.present(ac,completion: nil)
              }
}

这是注解的类:

import Foundation
import MapKit

class FireMarkerView: MKAnnotationView {
  override var annotation: MKAnnotation? {
    willSet {
      guard let fire = newValue as? Fire else {
        return
      }
      canShowCallout = true
      calloutOffset = CGPoint(x: -5,y: 5)
      rightCalloutAccessoryView = UIButton(type: .detailDisclosure)
      image = fire.image
    }
  }
}

这是模型的类:

import Foundation
import MapKit

class Fire: NSObject,MKAnnotation {
  let title: String?
  let county: String?
  let city: String?
  let incidentTypeCategory: String?
  let coordinate: CLLocationCoordinate2D
  let percentContained: Int?
  let lastUpdateDateTime: Int?
    

  init(
    title: String?,county: String?,city: String?,incidentTypeCategory: String?,coordinate: CLLocationCoordinate2D,percentContained: Int?,lastUpdateDateTime: Int?
  ) {
    self.title = title
    self.county = county
    self.city = city
    self.incidentTypeCategory = incidentTypeCategory
    self.coordinate = coordinate
    self.percentContained = percentContained
    self.lastUpdateDateTime = lastUpdateDateTime

    super.init()
  }


init?(feature: MKGeoJSONFeature) {
  // 1
  guard
    let point = feature.geometry.first as? MKPointAnnotation,let propertiesData = feature.properties,let json = try? JSONSerialization.jsonObject(with: propertiesData),let properties = json as? [String: Any]
    else {
      return nil
  }

  // 2
    
  title = ((properties["IncidentName"] as? String ?? "Unknown") + " Wildfire")
  county = ((properties["POOCounty"] as? String ?? "Unknown") + " County")
  city = properties["POOCity"] as? String
  incidentTypeCategory = properties["IncidentTypeCategory"] as? String
  coordinate = point.coordinate
  percentContained = properties["PercentContained"] as? Int
  lastUpdateDateTime =  properties["ModifiedOnDateTime_dt"] as? Int
  
  super.init()
}
    var subtitle: String? {
        return (county)
    }
    
    var image: UIImage {
      guard let name = incidentTypeCategory else {
        return #imageLiteral(resourceName: "RedFlame")
      }

      switch name {
      case "RX":
        return #imageLiteral(resourceName: "YellowFlame")
      default:
        return #imageLiteral(resourceName: "RedFlame")
      }
    }
}

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)