2016-11-25 54 views
0

我想打開一個新的viewcontroller,當我點擊PinAnnotation。但ViewForannotation不會打電話,當我點擊,但它顯示彈出消息,當我點擊Pin。不知道發生了什麼。這是我的代碼:ViewForAnnotation無法在Swift 3中調用

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

} 

這是我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 
     } 
    } 
} 

我使用Geofire獲得特定半徑附近的用戶,然後引腳用戶。請幫忙。

回答

4

你是在說:

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

這將肯定不會被調用。在斯威夫特3,正確的簽名是:

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

所有你需要做的就是參考文檔:

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

+0

太謝謝你了@馬特 –

+0

感謝馬特,我也有類似的問題,它出現了瑞士法郎的Xcode ift 3轉換器錯誤地將我的Swift 2代碼轉換爲'func mapView(mapView:MKMapView,viewFor annotation:MKAnnotation) - > MKAnnotationView? – Eugene

+2

@Eugene是的,轉換器不是100%可靠的,可選的協議方法是主要它可能會行爲不端。很大程度上取決於你在哪裏聲明這個視圖控制器是一個MKMapViewDelegate。 – matt

0

在同時仍使用正確的簽名以防別人也有同樣的問題,確保你設置你的MapView的委託:

override func viewDidLoad() { 
    super.viewDidLoad() 

    mapView.delegate = self 
}