Noir3
Noir3

Reputation: 1

Pass data in swift from one class to another

I have an app where a user takes a photo and he creates the annotation on the map with this photo, the photo has to be transferred to ImageAnnotation class and than a pin must be created on the map

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")
    }
}

Upvotes: -1

Views: 93

Answers (1)

Duncan C
Duncan C

Reputation: 131398

You posted a whole bunch of code that isn't relevant to your question. You should narrow it down to the code specific to your question (The class definition for your map view controller definition, plus the plusPressed IBAction method, the image picker delegate methods, the map view delegate methods, and your classes and methods for your custom annotation and annotation view classes.

You also did not have your code formatted correctly. I edited your question and put all of your code inside triple backticks so it would show up correctly.

Your code won't work as written. Your plusPressed() method creates an MKPointAnnotation object instead if your custom ImageAnnotation object. Your plusPressed() method should create and return an ImageAnnotation object instead.

You have your mapView(_:viewFor:) method nested inside your plusPressed() method, which does not make sense. You want the mapView(_:viewFor:) at the top level of your view controller class (or whatever class is the map view delegate. In your case that's the view controller.)

You should have your plusPressed() invoke the image picker, and only create an add an ImageAnnotation to the map if the user selects an image and presses OK. (You'd put code in your image picker's didFinishPickingMediaWithInfo method that would take the user-selected image, use it to create an ImageAnnotation, and add that annotation to the map.)

Upvotes: 0

Related Questions