2012-03-29 8 views
4

Gibt es eine Möglichkeit, ein Callout anzuzeigen, wenn eine Person ein MKPolylineView berührt? Ich habe versucht, einen UITapGestureRecognizer hinzuzufügen und im Selektor eine Legende in einer Koordinate anzuzeigen. aber hat nicht funktioniert. irgendwelche Vorschläge, dies zu machen?Callout von MKPolylineView?

folgende ist, was ich

- (MKOverlayView *)mapView:(MKMapView *)mapa viewForOverlay:(id <MKOverlay>)overlay 
     self.polylineView = [[MKPolylineView alloc] initWithPolyline: self.polyline]; 
     self.polylineView.strokeColor = [UIColor blackColor]; 
     self.polylineView.lineWidth = 5.0; 
     self.polylineView.alpha = 0.7; 
     UITapGestureRecognizer *touchOnView = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(addBubble:)]; 
     [touchOnView setNumberOfTapsRequired:1]; 
     [touchOnView setNumberOfTouchesRequired:1]; 
     [self.polylineView addGestureRecognizer:touchOnView]; 

Antwort

8

Sehr interessante Frage in Methode versucht - ich noch nie eine Gestenerkenner des Setzens auf einer Karte Overlay gedacht habe. Mit etwas Experimentieren habe ich festgestellt, dass es möglich ist, einen Tipp auf die MKPolylineView zu erkennen. Wie Sie festgestellt haben, funktionieren die Tap-Gesten nicht auf Karten-Overlays. Stattdessen habe ich statt der MKPolylineView die Tippgeste auf die MKMapView gesetzt. Dann den Wasserhahn zu behandeln:

- (void)handleTapGesture:(UIGestureRecognizer*)gestureRecognizer 
{ 
    if (measureLine != nil) 
    { 
     UIView* hitView = [self.polylineView hitTest:[gestureRecognizer locationInView:self.polylineView] withEvent:nil]; 
    } 
} 

hitView wird gleich Null sein, wenn Ihr Leitungs außerhalb der MKPolylineView ist, oder es wird self.polylineView wenn der Hahn drin ist.

Allerdings, das könnte sich nicht so verhalten, wie Sie möchten. Für horizontale und vertikale Linien funktioniert es perfekt, da die Größe der darunter liegenden Ansicht in etwa der Größe der Linie entspricht. Aber für eine 45-Grad-Linie muss die darunter liegende Ansicht viel größer sein als die Linie, da es eine achsenbündige Begrenzungsbox (AABB) ist. Wenn Sie an eine 45-Grad-Linie denken, um sie nur mit horizontalen und vertikalen Linien zu umschließen, werden Sie mit einer großen Fläche enden - viel größer, als Sie Abgriffe erkennen würden.

z.B.

Aber die Verwendung einer Tippgeste oder des Treffertests führt immer dazu, dass Taps in diesen AABBs erkannt werden. Also unabhängig davon, wo Sie versuchen, Ihre Geste anzuhängen - z. an die MKPolylineView wie Sie versucht haben, oder an die MKMapView, werden Sie falsche Ergebnisse erhalten. Das Problem wird bei längeren Linien schlimmer - wenn Sie sich eine Linie vorstellen, die von rechts oben in Ihrer Kartenansicht nach links unten verläuft, würde die AABB, die Sie umschließen müssten, den gesamten Bereich der Kartenansicht abdecken, was bedeutet, dass a Tippen Sie oben links oder unten rechts würde als die MKPolylineView Treffer interpretiert werden.

das Problem zu lösen, würde ich den folgenden Ansatz vorschlagen:

  • eine Anzapfung Gestenerkenner auf der Kartenansicht verwenden
  • In Ihrer Methode, die den Hahn Griffe:
    • den Bildschirm umwandeln Tippen Sie auf eine Kartenkoordinate
    • Schleife durch jede Ihrer Polylinien (es sei denn, Sie haben nur 1)
    • für jeden Punkt in der Polylinie nehmen Sie das Liniensegment, dass conne cts, die auf den nächsten Punkt zeigen und den Abstand Ihrer Kartenkoordinaten von dieser Linie berechnen. Verwenden Sie Trigonometrie, um dies zu berechnen.
      • , wenn der Abstand zu diesem Segment sehr nahe ist, dann stoppen Sie den Rest der Segmente überprüft und zu handhaben, was Beschriftungen usw. Sie
      • , wenn der Abstand nicht in der Nähe ist, dann gehen Sie zum nächsten Punkt und die Linie zeigen wollten, Segment, das es auf den nächsten, aber ein Punkt

Dieser Ansatz verbindet, ist garantiert, unabhängig von der Dauer Ihres Polylinien zu arbeiten, oder welchem ​​Winkel sie sind. Es gibt keine Bedenken der AABB. Der Nachteil ist, dass all diese Entfernungsberechnungen rechenintensiv sein können. Wenn Ihre Polylinien also aus einer großen Anzahl von Punkten bestehen oder wenn Sie eine große Anzahl von Polylinien haben, können Sie möglicherweise nicht alle diese Berechnungen durchführen ohne zu blockieren, dass die Benutzeroberfläche reagiert, was bedeutet, dass Sie sie in einen Hintergrundthread verschieben müssen. Wenn Sie nur eine Handvoll Polylinien haben und/oder aus wenigen Punkten bestehen, ist alles in Ordnung.