2016-12-23 38 views
0

Ich habe einige Erfahrung mit MKMapView und MKPointAnnotation, die ich verwendet habe, um einige Pin auf einer Karte zu setzen. Dieses Mal versuche ich, einen Schritt weiter zu gehen und MKPinAnnotationView zu verwenden, um ein Etikett zusammen mit einigen der Pins zu schreiben.MKPinAnnotationView zeigt keinen Titel an

Leider funktioniert es nicht so, wie ich es erwarte.

Hier ist, was ich tun möchte:

Ich habe eine Karte (ein MKMapView Objekt) und wenn ich es berühren, habe ich am Berührungspunkt einen Stift, dann einige Berechnung durchgeführt wird, und das gibt mir ein zweiter Punkt auf der Karte. Ich lege einen zweiten Pin (am zweiten Punkt), auf diesen letzten Pin möchte ich ein Label setzen, sagen "Hallo Second!". Hier

ist der entsprechende Code:

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

Hier ist, was passiert, sind die Stifte wie erwartet platziert, aber ich habe keine Aufkleber auf dem zweiten sehen. Ich habe auch bemerkt, dass, wenn ich klopfe, wo der zweite Pin zufällig ist (in diesem Fall wird der 2. Pin am selben Ort bleiben), dann erscheint das Etikett (wie es immer tun sollte). Wenn ich erneut tippe (nicht so nah), verschwindet das Etikett wieder (obwohl es nicht sollte).

Gibt es etwas in meinem Code (oben), das ist nicht richtig? Jeder relevante Tipp wird geschätzt.

Antwort

0

Diese i'have für Google Map verwendet, aber es sollte in

self.secondPoint.title = "Hello Second!" 

ist der Titel callout Ansicht für u ..

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

Nun, ich sollte nicht ein anderes SDK (Google Maps API) verwenden müssen, um dies zu tun. Ich nehme an, wenn ich die Dinge richtig mache, sollte es funktionieren wie ich will. – Michel

+0

Ich gebe Ihnen nur die grobe Idee Ich bin nicht gefragt, Google Map zu verwenden. – hussain

1

Titel beziehen Sie sich arbeiten, wenn kommt Sie tippen auf den Anmerkungsstift. Wenn Sie das Label zusammen mit dem Pin-Bild jedes Mal anzeigen möchten, können Sie wahrscheinlich MKAnnotationView ableiten und das Label dort in Ihrer benutzerdefinierten Pin-Ansicht hinzufügen. Sie können

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

Ich habe einige Zeit damit verbracht, an deinem Vorschlag zu experimentieren und es hat mir sehr geholfen zu verstehen, wie das alles funktioniert. Hier ist meine aktuelle Frage: Wenn die Funktion "func mapView (_ mapView: MKMapView, viewFor Anmerkung: MKAnnotation) -> MKAnnotationView?" wird genannt. Wie kann ich wissen, ob es für TouchPoint oder für SecondPoint aufgerufen wird? Gibt es eine Verbindung zwischen MKPointAnnotation und MKAnnotation oder etwas, das ich verwenden kann. – Michel

+0

@Michel können Sie überprüfen, ob die angetippte Anmerkung der eine oder andere durch ein einfaches 'if (annotation == touchPoint) {// tue etwas}} sonst if (annotation == secondPoint) {// tue etwas anderes} '. Ich hoffe, das hilft Ihnen –

+0

@Reinier: Dies funktioniert nicht, weil Annotation vom Typ MKAnnotation und TouchPoint vom Typ MKPointAnnotation ist; Sie erhalten eine Beschwerde vom Compiler. Aber ich fand einen anderen Weg: Vergleichen der Koordinaten, mit diesem Code "if ((annotation.coordinate.latitude! = TouchPoint.coordinate.latitude) || (annotation.coordinate.longitude! = TouchPoint.coordinate.longitude)) {. ..} ". Ehrlich gesagt mag ich es nicht, aber ich habe nichts besseres für jetzt. – Michel

0

Diese Lösung Versuchen Sie in folgenden Art und Weise anpassen Dieses Sie

Erste MyAnnotation Stift

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 Delegatmethode

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 

    } 

Das ist mein annation erstellen helfen wird Klasse. Diese Klasse erfüllt alle Ihre Probleme

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

}