快速将数据从一类传递到另一类

时间:2020-10-16 16:43:34

标签: swift annotations mkmapview mkannotation mkannotationview

我有一个应用程序,用户在其中拍照,然后他用这张照片在地图上创建注释,照片必须转移到ImageAnnotation类,然后必须在地图上创建图钉

import UIKit
import MapKit
import CoreLocation
import Firebase

class MapViewController: UIViewController, CLLocationManagerDelegate, UIImagePickerControllerDelegate, UINavigationControllerDelegate {
    
    
    @IBOutlet weak var MapButton: UITabBarItem!
    @IBOutlet weak var mapView: MKMapView!
    
    let locationManager = CLLocationManager()
    var currentLocation: CLLocation!
    let regionInMeters: Double = 10000
    
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        navigationController?.isNavigationBarHidden = true
        
        let db = Firestore.firestore()
        
        db.collection("locations").getDocuments() { [self] (querySnapshot, err) in
            if let err = err {
                print("Error getting documents: \(err)")
            } else {
                for document in querySnapshot!.documents {
                    if let coords = document.get("pinLocation") {
                        let point = coords as! GeoPoint
                        let lat = point.latitude
                        let lon = point.longitude
                        let annotation = MKPointAnnotation()
                        annotation.coordinate = CLLocationCoordinate2D(latitude: lat, longitude: lon)
                        mapView.addAnnotation(annotation)
                    }
                }
            }
        }
    }
    
    override func viewDidDisappear(_ animated: Bool) {
        super.viewDidDisappear(animated)
        navigationController?.isNavigationBarHidden = false
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
        checkLocationServices()
        locationManager.delegate = self
    }
    
    func setupLocationManager() {
        locationManager.delegate = self
        locationManager.desiredAccuracy = kCLLocationAccuracyBest
    }
    
    func centerViewOnUserLocation() {
        if let location = locationManager.location?.coordinate {
            let region = MKCoordinateRegion.init(center: location, latitudinalMeters: regionInMeters, longitudinalMeters: regionInMeters)
            mapView.setRegion(region, animated: true)
        }
    }
    
    func checkLocationServices() {
        if CLLocationManager.locationServicesEnabled() {
            setupLocationManager()
            checkLocationAuthorization()
        } else {
            
        }
    }
    
    func checkLocationAuthorization() {
        switch CLLocationManager.authorizationStatus() {
        case .authorizedWhenInUse:
            mapView.showsUserLocation = true
            centerViewOnUserLocation()
            locationManager.startUpdatingLocation()
            break
        case .denied:
            break
        case .notDetermined:
            locationManager.requestWhenInUseAuthorization()
        case .restricted:
            break
        case .authorizedAlways:
            break
        }
    }
    
    @IBAction func plusPressed(_ sender: UIButton) {
        
//        guard let currLoc = locationManager.location else { return }
        
        currentLocation = locationManager.location
        
        let annotation = MKPointAnnotation()
        annotation.coordinate = CLLocationCoordinate2D(latitude: currentLocation.coordinate.latitude, longitude: currentLocation.coordinate.longitude)
        mapView.addAnnotation(annotation)
        
        let picker  = UIImagePickerController()
        picker.sourceType = .camera
        picker.delegate = self
        present(picker, animated: true)
        
        func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
                if annotation.isKind(of: MKUserLocation.self) {  //Handle user location annotation..
                    return nil  //Default is to let the system handle it.
                }

                if !annotation.isKind(of: ImageAnnotation.self) {  //Handle non-ImageAnnotations..
                    var pinAnnotationView = mapView.dequeueReusableAnnotationView(withIdentifier: "DefaultPinView")
                    if pinAnnotationView == nil {
                        pinAnnotationView = MKPinAnnotationView(annotation: annotation, reuseIdentifier: "DefaultPinView")
                    }
                    return pinAnnotationView
                }

                //Handle ImageAnnotations..
                var view: ImageAnnotationView? = mapView.dequeueReusableAnnotationView(withIdentifier: "imageAnnotation") as? ImageAnnotationView
                if view == nil {
                    view = ImageAnnotationView(annotation: annotation, reuseIdentifier: "imageAnnotation")
                }

                let annotation = annotation as! ImageAnnotation
                view?.image = annotation.image
                view?.annotation = annotation

                return view
            }
        
    }
    
    func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
//        guard let location = locations.last else { return }
//        let center = CLLocationCoordinate2D(latitude: location.coordinate.latitude, longitude: location.coordinate.longitude)
//        let region = MKCoordinateRegion.init(center: center, latitudinalMeters: regionInMeters, longitudinalMeters: regionInMeters)
//        mapView.setRegion(region, animated: true)
    }
    
    func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
        checkLocationAuthorization()
    }
    
    func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
        picker.dismiss(animated: true, completion: nil)
    }
    
    func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
        guard let image = info[UIImagePickerController.InfoKey.originalImage] as? UIImage else {
            return
        }
    }
    
}

class ImageAnnotation : NSObject, MKAnnotation {
    var coordinate: CLLocationCoordinate2D
    var image: UIImage?
    var color: UIColor?

    override init() {
        self.coordinate = CLLocationCoordinate2D()
        self.image = ///// Here must go the image from imagePickerController
        self.color = UIColor.systemGreen
    }
}

class ImageAnnotationView: MKAnnotationView {
    private var imageView: UIImageView!

    override init(annotation: MKAnnotation?, reuseIdentifier: String?) {
        super.init(annotation: annotation, reuseIdentifier: reuseIdentifier)

        self.frame = CGRect(x: 0, y: 0, width: 20, height: 20)
        self.imageView = UIImageView(frame: CGRect(x: 0, y: 0, width: 20, height: 20))
        self.addSubview(self.imageView)

        self.imageView.layer.cornerRadius = 25
        self.imageView.layer.masksToBounds = true
    }

    override var image: UIImage? {
        get {
            return self.imageView.image
        }

        set {
            self.imageView.image = newValue
        }
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}

1 个答案:

答案 0 :(得分:0)

您发布了一堆与您的问题无关的代码。您应该将其范围缩小到特定于问题的代码(地图视图控制器定义的类定义,以及plusPressed IBAction方法,图像选择器委托方法,地图视图委托方法以及自定义批注的类和方法和注释视图类。

您还没有正确设置代码格式。我编辑了您的问题,并将所有代码放入三个反引号中,以便正确显示。

您的代码将无法正常运行。如果您的自定义plusPressed()对象,则您的MKPointAnnotation方法将创建一个ImageAnnotation对象。您的plusPressed()方法应创建并返回一个ImageAnnotation对象。

您将mapView(_:viewFor:)方法嵌套在plusPressed()方法内,这没有任何意义。您希望mapView(_:viewFor:)位于视图控制器类的顶层(或地图视图委托的任何类。在您的情况下,这就是视图控制器。)

您应该让plusPressed()调用图像选择器,并且只有在用户选择图像并按OK的情况下,才能在地图上添加一个ImageAnnotation。 (您已将代码放入图像选择器的didFinishPickingMediaWithInfo方法中,该方法将获取用户选择的图像,使用它来创建ImageAnnotation,并将该注释添加到地图中。)