2016-12-23 103 views
0

我已經有一些使用MKMapViewMKPointAnnotation的經驗,我曾經在地圖上放置了一些別針。 這次我想更進一步,使用MKPinAnnotationView來寫一個標籤和一些引腳。MKPinAnnotationView不顯示標題

不幸的是,它並不像我預期的那樣工作。

這是我想做的事:

我有一個圖表(的MKMapView對象),當我觸摸它,我把一根鋼釘在觸摸點,然後進行一些計算,這給了我一個地圖上的第二個點。我把第二個引腳(位於第二個點)放在最後一個引腳上,我想放一個標籤,說「Hello Second!」。

下面是相關代碼:

class ViewController: UIViewController, MKMapViewDelegate { 
    var mapView:MKMapView!, touchPoint,secondPoint:MKPointAnnotation! 

    override func viewDidLoad() { 
     super.viewDidLoad() 
     mapView = MKMapView() 
     ........... 
     let mapTap = UITapGestureRecognizer(target: self, 
              action: #selector(ViewController.mapTouchHandler)) 
     mapView.addGestureRecognizer(mapTap) 
    } 


    func mapTouchHandler(gesture:UITapGestureRecognizer) { 
     ........... 
     // Compute map coordinates for the touch point (tapGeoPoint). 

     if touchPoint == nil { 
      touchPoint = MKPointAnnotation() 
      mapView.addAnnotation(touchPoint); 
     } 

     touchPoint.coordinate = CLLocationCoordinate2D(latitude: tapGeoPoint.latitude, 
                 longitude: tapGeoPoint.longitude) 
     ........... 
     computeSecondPoint(url: someComputedURL) 
    } 


    func computeSecondPoint(url searchURL:String) { 
     let reqURL = NSURL(string: searchURL)!, session = URLSession.shared, 
     task = session.dataTask(with: reqURL as URL) { 
      (data: Data?, response: URLResponse?, error: Error?) in 
      if error == nil { 
       do {let allData = try JSONSerialization.jsonObject(with: data!, options: .mutableContainers) as? NSArray 
        ................. 
        // Compute map coordinates for the second point (secondPointCoord). 

        if self.secondPoint == nil { 
         self.secondPoint = MKPointAnnotation() 
         self.mapView.addAnnotation(self.secondPoint) 
        } 

        DispatchQueue.main.async { 
         () -> Void in 
         self.secondPoint.coordinate = CLLocationCoordinate2D(latitude: secondPointCoord.latitude, 
                      longitude: secondPointCoord.longitude) 
         self.secondPoint.title = "Hello Second!" 
        } 
       } catch let error as NSError {print(error.localizedDescription)} 
      } else { 
       print("Error inside \(#function):\n\(error)") 
      } 
     } 

     task.resume() 

    } 


    func mapView(_ mapView: MKMapView, 
       viewFor annotation: MKAnnotation) -> MKAnnotationView? { 
     let identifier = "pin" 
     var view: MKPinAnnotationView 
     if let dequeuedView = mapView.dequeueReusableAnnotationView(withIdentifier: identifier) 
      as? MKPinAnnotationView { 
      dequeuedView.annotation = annotation 
      view = dequeuedView 
     } else { 
      view = MKPinAnnotationView(annotation: annotation, reuseIdentifier: identifier) 
      view.canShowCallout = true 
      view.calloutOffset = CGPoint(x: -5, y: 0) 
     } 
     return view 
    } 
} 

現在,這裏是什麼情況,如預期的引腳放置,但我沒有看到第二個的任何標籤。 我還注意到,如果我點擊第二個引腳碰巧的地方(在這種情況下,第二個引腳將停留在同一個地方),那麼標籤就會出現(因爲它應該總是這樣做)。如果我再次點擊(不是那麼近),那麼標籤會再次消失(儘管它不應該)。

有沒有在我的代碼(上面)是不正確的? 任何相關的提示將不勝感激。

回答

0

這i'have使用谷歌地圖,但它應該ü工作..

let position = CLLocationCoordinate2DMake(latitude,longitude) 
let location = GMSMarker(position: position) 
location.icon = image 
location.icon? = self.imageWithImage(image, scaledToSize: CGSize(width: 50.0, height: 50.0)) 
location.title = "the photo is clicked here!!" 
location.map = MapView 
+0

那麼,我不應該使用不同的SDK(Google Maps API)才能做到這一點。我想如果我以正確的方式做事情,它應該按我的意願工作。 – Michel

+0

我只是給你粗略的想法 我不是要求使用谷歌地圖。 – hussain

1

標題你是指在

self.secondPoint.title = "Hello Second!" 

是標註視圖的標題這時候來您點擊註釋引腳。如果您希望每次您可以繼承MKAnnotationView的子類並在標籤中添加標籤,那麼您需要在標籤中顯示標籤。您可以按以下方式

class CustomAnnotationView : MKPinAnnotationView 
{ 
    let helloLabel:UILabel = UILabel.init(frame:CGRectMake(0, 0, 100, 40)) //your desired frame 

    func showLabel(title : String) 
    { 
     helloLabel.text = title 
     helloLabel.textAlignment = .Center 
     //set further properties 
     self.addSubview(helloLabel) 
    } 

    fun hideLabel() { 
     helloLabel.removeFromSuperview() 
    } 
} 
+0

我花了一些時間試驗你的建議,它幫助我瞭解了所有這些工作。這裏是我現在的問題:當函數「func mapView(_mapView:MKMapView, viewFor annotation:MKAnnotation) - > MKAnnotationView?」叫做。我如何知道它是否被稱爲touchPoint或secondPoint? MKPointAnnotation和MKAnnotation之間有什麼聯繫,或者我可以使用。 – Michel

+0

@Michel你可以通過一個簡單的if(註解== touchPoint){//做某事} else if(註解== secondPoint){//做別的事情}來檢查註釋是否是一個或另一個。我希望這可以幫助你 –

+0

@Reinier:這不起作用,因爲註釋的類型是MKAnnotation,而touchPoint的類型是MKPointAnnotation;你會收到編譯器的投訴。但是我發現了一種不同的方式:比較座標,用這個代碼「if((annotation.coordinate.latitude!= touchPoint.coordinate.latitude)||(annotation.coordinate.longitude!= touchPoint.coordinate.longitude)){ ..}」。坦率地說,我不喜歡它,但現在我沒有更好的了。 – Michel

0

定製嘗試這種解決方案這將幫助你

首先創建MyAnnotation銷

if(geo_accuracy == "0") 
      { 
       colorofpin = .Blue 
      }else if (geo_accuracy == "1") 
      { 
       colorofpin = .Red 
      }else 
      { 
       colorofpin = .Green 
      } 
      var locationAnnotation = MyAnnotation(coordinate: location, 
       title: p_user_name!, 
       subtitle: "", 
       pinColor: colorofpin, 
       getTag:i) 


      /* And eventually add them to the map */ 

      //aryNotation.addObject(locationAnnotation) 

      aryNotation.append(locationAnnotation) 

MapView的委託方法

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

      if annotation is MyAnnotation == false{ 
       return nil 
      } 

      /* First typecast the annotation for which the Map View has 
      fired this delegate message */ 
      let senderAnnotation = annotation as! MyAnnotation 



      // -------------------------- For ios 9 ------------------- 


      let reuseId = "pin" 
      var pinView = mapView.dequeueReusableAnnotationViewWithIdentifier(reuseId) 

      if pinView == nil { 
       pinView = MKAnnotationView(annotation: annotation, reuseIdentifier: reuseId) 
       pinView!.canShowCallout = true 

      }else{ 
       pinView!.annotation = annotation 
      } 
      pinView!.tag = senderAnnotation.getTag; 

      // print(senderAnnotation.getTag) 

      if annotation is MyAnnotation { 

       //print(senderAnnotation.pinColor) 
       if(senderAnnotation.pinColor == .Red) 
       { 
        if(currentIndex == senderAnnotation.getTag) 
        { 
         //print("currentIndex==\(currentIndex)********") 
         pinView!.image = UIImage(named: "jivemap_pin_rough_o.png") 
         pinView!.layer.zPosition = 1 
         pinView?.bringSubviewToFront(self.view) 
         // pinView!.superview!.bringSubviewToFront(view) 
        }else 
        { 
         pinView!.image = UIImage(named: "jivemap_pin_rough_g.png") 
         pinView!.layer.zPosition = 0 
        } 
       } 
       else 
       { 

       if(currentIndex == senderAnnotation.getTag) 
       { 
        //print("currentIndex==*********\(currentIndex)********") 
        pinView!.image = UIImage(named: "jivemap_pin_o.png") 
        pinView!.layer.zPosition = 1 


       }else 
       { 
        pinView!.image = UIImage(named: "jivemap_pin_g.png") 
        pinView!.layer.zPosition = 0 
       } 
      } 

       pinView!.rightCalloutAccessoryView = UIButton(type: UIButtonType.DetailDisclosure) as UIView 
       // pinView 
       // return pinView 
      } 





      return pinView 
      //return annotationView 

    } 

這是我annation類。此課程將全面解決您的所有問題

import UIKit 
import MapKit 

/* This will allow us to check for equality between two items 
of type PinColor */ 
func == (left: PinColor, right: PinColor) -> Bool{ 
    return left.rawValue == right.rawValue 
} 

/* The various pin colors that our annotation can have */ 
enum PinColor : String{ 
    case Blue = "Blue" 
    case Red = "Red" 
    case Green = "Green" 
    case Purple = "Purple" 

    /* We will convert our pin color to the system pin color */ 
    func toPinColor() -> MKPinAnnotationColor{ 
     switch self{ 
     case .Red: 
      return .Red 
     case .Green: 
      return .Green 
     case .Purple: 
      return .Purple 
     default: 
      /* For the blue pin, this will return .Red but we need 
      to return *a* value in this function. For this case, we will 
      ignore the return value */ 
      return .Red 
     } 
    } 
} 

class MyAnnotation: NSObject, MKAnnotation { 
    var coordinate: CLLocationCoordinate2D 
    var title: String? 
    var subtitle: String? 
    var pinColor: PinColor! 
    var getTag:Int! 
    var annoationIndex = 0 

    init(coordinate: CLLocationCoordinate2D, 
     title: String, 
     subtitle: String, 
     pinColor: PinColor, 
     getTag: Int){ 
      self.coordinate = coordinate 
      self.title = title 
      self.subtitle = subtitle 
      self.pinColor = pinColor 
      self.getTag = getTag 
      super.init() 
    } 

    convenience init(coordinate: CLLocationCoordinate2D, 
     title: String, 
     subtitle: String, 
     gettag: Int){ 
      self.init(coordinate: coordinate, 
       title: title, 
       subtitle: subtitle, 
       pinColor: .Blue, 
       getTag: gettag) 
    } 

}