swiftmkmapviewmkpinannotationviewmkmapviewdelegate

ViewForAnnotation not Called in Swift 3


I want to open a new viewcontroller when i click the PinAnnotation. But ViewForannotation is not calling when i click, But It is showing a pop up message when i click on Pin. Don't know what is happening. Here is my Code:

import UIKit
import MapKit

class Pin: NSObject, MKAnnotation {

    var coordinate: CLLocationCoordinate2D
    var key: String
    var title: String?
    var age: String?
    var category: String?
    var color: MKPinAnnotationColor = MKPinAnnotationColor.purple
    var subtitle: String?

    init(key: String, name: String , age: String , category: String , color: MKPinAnnotationColor) {
        self.coordinate = CLLocationCoordinate2D(latitude: 0, longitude: 0)
        self.key = key
        self.title = name
        self.color = color
        self.subtitle = age
        self.category = category


        //print("keyy: ", key)
        //print("title: ", name)
    }

}

This is my MapViewControllerClass:

import UIKit
import GeoFire
import MapKit
import Firebase
import CoreLocation


class MapViewController: UIViewController, CLLocationManagerDelegate, MKMapViewDelegate, UIAlertViewDelegate {

    //@IBOutlet weak var sidebarButton: UIBarButtonItem!
    @IBOutlet weak var mapView: MKMapView!
    //@IBOutlet weak var chatbarButton: UIBarButtonItem!

    /* ---> NEW MAP-IT <--- */

    let locationManager = CLLocationManager()

    let imagePicker = UIImagePickerController()
    var regionQuery: GFRegionQuery?
    var foundQuery: GFCircleQuery?
    var annotations: Dictionary<String, Pin> = Dictionary(minimumCapacity: 8)

    var lastExchangeKeyFound: String?
    var lastExchangeLocationFound: CLLocation?

    var location: CLLocation!
   // var location = CLLocation(latitude: 37.33233141, longitude: -122.0312186)
    //let location = CLLocation(latitude: 37.33209999, longitude: -122.0326666)

    var circle: MKCircle!

    var index = 0
    var val1Lat: Double!
    var val2Lat: Double!
    var val1Long: Double!
    var val2Long: Double!

    var flag = false
    var userName = ""
    var age = ""
    var category = ""
    var uid = ""

    override func viewDidLoad() {
        super.viewDidLoad()

        uid = DataService.ds.currentUserID
        self.mapView.delegate = self
        // locationManager.requestAlwaysAuthorization()

        if (CLLocationManager.authorizationStatus() == CLAuthorizationStatus.authorizedAlways) || (CLLocationManager.authorizationStatus() == CLAuthorizationStatus.authorizedWhenInUse) {
            print("Authorized")
            locationManager.delegate = self
            locationManager.desiredAccuracy = kCLLocationAccuracyBest
            locationManager.startUpdatingLocation()
        } else {
            print("Application is not authorized to use location services")
            //- TODO: Unauthorized, requests permissions again and makes recursive call
        }
    }

    func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
        if manager.location?.coordinate != nil {
            if flag == true {
                if (location.coordinate.latitude != manager.location?.coordinate.latitude) || (location.coordinate.longitude != manager.location?.coordinate.longitude) {

                    location = manager.location!//.coordinate
                    print("lat: \(location.coordinate.latitude)")
                    print("long: \(location.coordinate.longitude)")
                    animateMap(location: location)

                    let key = DataService.ds.currentUserID
                    geofire!.setLocation(location, forKey: key)
                }
            } else {
                print("Else:LocationManag")
                location = manager.location!
                print("lat: \(location.coordinate.latitude)")
                print("long: \(location.coordinate.longitude)")

                animateMap(location: location)
                flag = true

                let key = DataService.ds.currentUserID
                geofire!.setLocation(location, forKey: key)
            }
        }
    }

    override func viewDidAppear(_ animated: Bool) {
        print("DidAppear")
        self.mapView.userLocation.addObserver(self, forKeyPath: "location", options: NSKeyValueObservingOptions(), context: nil)
    }
    override func viewDidDisappear(_ animated: Bool) {
        print("DidDisAppear")
        locationManager.stopUpdatingLocation()
        self.mapView.userLocation.removeObserver(self, forKeyPath: "location", context: nil)
    }

    override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
        print("In observer")
        if (self.mapView.showsUserLocation) && (self.mapView.userLocation.location) != nil
        {
            let span = MKCoordinateSpanMake(0.0125, 0.0125)
            let region = MKCoordinateRegion(center: self.mapView.userLocation.location!.coordinate /*location.coordinate*/, span: span)

            self.mapView.setRegion(region, animated: true)




            if foundQuery == nil {
                 print("FoundQuery nill")
                foundQuery = geofire?.query(at: /*location*/self.mapView.userLocation.location, withRadius: 0.2)

                foundQuery!.observe(GFEventType.keyEntered, with: { (key: String?, location:CLLocation?)  -> Void in

                    //print("here")
                    DataService.ds.userRef.child(key!).observeSingleEvent(of: .value, with: { (snapshot) in

                        if let userDictionary = snapshot.value as? Dictionary<String , AnyObject>
                        {
                            self.userName = userDictionary["firstName"] as! String
                            self.age = userDictionary["age"] as! String
                            self.category = userDictionary["category"] as! String
                        }


                        self.lastExchangeKeyFound = key
                        self.lastExchangeLocationFound = location

                        if key != DataService.ds.currentUserID {
                            let annotation = Pin(key: key!, name: self.userName , age: self.age , category: self.category , color: MKPinAnnotationColor.green)

                            annotation.coordinate = (location?.coordinate)!
                            annotation.title = self.userName + " - " + self.age
                            annotation.subtitle = self.category
//                            if self.category == "Trainer"{
//                                annotation.color = MKPinAnnotationColor.green
//                            }else{
//                                annotation.color = MKPinAnnotationColor.purple
//                            }
                            self.mapView.addAnnotation(annotation)
                            self.annotations[key!] = annotation
                        }
                    })

                    self.foundQuery?.observe(.keyExited, with: { (key, location) in
                        if key != DataService.ds.currentUserID {
                            if self.annotations[key!] != nil {
                                self.mapView.removeAnnotation(self.annotations[key!]!)
                                self.annotations[key!] = nil
                            }
                        }
                    })
                })
            }
            else
            {
                foundQuery?.center = self.mapView.userLocation.location
            }
        }
    }

    //Click Event For Annotation:

//    func mapView(mapView: MKMapView!, annotationView view: MKAnnotationView!,
//                 calloutAccessoryControlTapped control: UIControl!) {
//        
//        if control == view.rightCalloutAccessoryView {
//            print("Disclosure Pressed! \(view.annotation?.subtitle)")
//        }
//        
//    }

    func mapView(mapView: MKMapView!, viewForAnnotation annotation: MKAnnotation!) -> MKAnnotationView! {

        print("inPin1")
        if annotation is Pin {
            print("inPin2")
            let pinAnnotationView = MKPinAnnotationView(annotation: annotation, reuseIdentifier: "myPin")

            pinAnnotationView.pinColor = .purple
            pinAnnotationView.isDraggable = true
            pinAnnotationView.canShowCallout = true
            pinAnnotationView.animatesDrop = true

            let deleteButton = UIButton.init(type: UIButtonType.custom) as UIButton
            // let deleteButton = UIButton.withType(UIButtonType.custom) as UIButton
            deleteButton.frame.size.width = 44
            deleteButton.frame.size.height = 44
            deleteButton.backgroundColor = UIColor.red
            deleteButton.setImage(UIImage(named: "xbutton"), for: .normal)

            pinAnnotationView.leftCalloutAccessoryView = deleteButton

            return pinAnnotationView
        }

        return nil
    }

    func mapView(mapView: MKMapView!, annotationView view: MKAnnotationView!, calloutAccessoryControlTapped control: UIControl!) {
        if let annotation = view.annotation as? Pin {
            mapView.removeAnnotation(annotation)
        }

    }



//    func mapView(mapView: MKMapView, viewForAnnotation annotation: MKAnnotation) -> MKAnnotationView {
//        var annotationView = MKPinAnnotationView(annotation: annotation, reuseIdentifier: "loc")
//        annotationView.canShowCallout = true
//        annotationView.rightCalloutAccessoryView = UIButton(type: .detailDisclosure)
//        return annotationView
//    }
//    
//    func mapView(mapView: MKMapView, didSelectAnnotationView view: MKAnnotationView) {
//        mapView.deselectAnnotation(view.annotation, animated: true)
//        var controller = self.storyboard!.instantiateViewController(withIdentifier: "DetailsPopover")
//        controller.annotation! = view.annotation
//        self.popover = UIPopoverController(contentViewController: controller)
//        self.popover.delegate = self
//        self.popover.presentPopoverFromRect(view.frame, inView: view.superview!, permittedArrowDirections: .Any, animated: true)
//    }


//    func mapView(_ mapView: MKMapView, annotationView view: MKAnnotationView, calloutAccessoryControlTapped control: UIControl) {
//        print("helloooo")
//        self.performSegue(withIdentifier: "detailView", sender: view)
//    }

//    func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
//        // simple and inefficient example
//        let annotationView = MKPinAnnotationView()
//        if category == "Trainer"{
//            annotationView.pinTintColor = .purple
//        }else{
//            annotationView.pinTintColor = .green
//        }
//        
//        
//        
//        return annotationView
//    }

    func animateMap(location: CLLocation)
    {
       // print("animate Map")
        let region = MKCoordinateRegionMakeWithDistance(location.coordinate, 1000, 1000)
        mapView.setRegion(region, animated: true)
        addRadiusCircle(location: location)
    }

    func addRadiusCircle(location: CLLocation)
    {
        //print("Add Radius")
        //self.mapView.delegate = self

        if circle != nil
        {
            self.mapView.remove(circle)
        }

        circle = MKCircle(center: location.coordinate, radius: 200 as CLLocationDistance)
        self.mapView.add(circle)
    }

    func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer
    {
        if overlay is MKCircle
        {
            let circle = MKCircleRenderer(overlay: overlay)
            circle.strokeColor = UIColor.red
            circle.fillColor = UIColor(red: 255, green: 0, blue: 0, alpha: 0.1)
            circle.lineWidth = 1
            return circle
        }
        else {
            let temp = MKOverlayRenderer()
            return temp
        }
    }
}

I am Using Geofire to get the nearby users in a particular radius and then pin that users. Please help.


Solution

  • You are saying:

    func mapView(mapView: MKMapView!, viewForAnnotation annotation: MKAnnotation!) -> MKAnnotationView!
    

    That will certainly never be called. In Swift 3, the correct signature is:

    func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView?
    

    All you have to do is consult the documentation:

    https://developer.apple.com/reference/mapkit/mkmapviewdelegate/1452045-mapview