Wie mache ich einen MKAnnotationView berührungssensitiv?

8

Ich habe derzeit eine Kartenansicht mit einigen Anmerkungen darauf. Ich habe die Anmerkung mit benutzerdefinierten Bildern. Das Problem, das ich beheben möchte, ist die Empfindlichkeit der Bilder. Wenn ich versuche, sie zu ziehen, fühlt es sich an, als müsste ich genau das Zentrum berühren, auf das ich fokussiere. Gibt es eine Möglichkeit, die Berührungsgrenzen größer zu machen?

    
Phong Le 27.12.2011, 19:04
quelle

4 Antworten

17

Um dies zu tun, müssen Sie die Unterklasse MKAnnotationView erstellen, um Ihre eigene benutzerdefinierte MKAnnotationView zu erstellen. Überschreiben Sie in Ihrer Unterklasse die folgenden Funktionen:

%Vor%

Dadurch können interaktive Ansichten (z. B. Tasten usw.) gedrückt werden. Die Standardimplementierung in MKAnnotationView ist nicht fest in pointInside und hitTest , da Druckvorgänge, die sich tatsächlich in einer Annotation befinden, an eine andere Annotation gesendet werden. Dazu wird das nächstgelegene Anmerkungszentrum für den Berührungspunkt ermittelt und die Ereignisse werden an diese Anmerkung gesendet, sodass sich eng beieinander liegende (überlappende) Anmerkungen nicht gegenseitig blockieren. In Ihrem Fall möchten Sie jedoch wahrscheinlich andere Anmerkungen blockieren, wenn der Benutzer die oberste Anmerkung auswählen und ziehen soll, so dass die oben genannte Methode wahrscheinlich Ihren Wünschen entspricht, oder Sie auf den richtigen Pfad setzen.

BEARBEITEN: Ich wurde in Kommentaren nach einer Beispielimplementierung von hitTest:withEvent: gefragt - das hängt davon ab, was genau Sie erreichen wollen. Die ursprüngliche Frage schlug vor, Bilder innerhalb der Anmerkung zu berühren und zu ziehen, während ich in meinem Fall einige Knöpfe in der Anmerkung habe, die ich interaktiv sein möchte. Hier ist mein Code:

%Vor%

Wie Sie sehen, ist das ganz einfach - Die MKAnnotationView -Implementierung (in der ersten Zeile meiner Implementierung als super bezeichnet) gibt nur die erste (äußerste) Sicht zurück, sie dringt nicht durch die Sichthierarchie, um zu sehen In welcher Unteransicht ist die Berührung tatsächlich drin. In meinem Fall überprüfe ich einfach, ob die Berührung in einer von drei Tasten ist und gebe diese zurück. Unter anderen Umständen können Sie einfache rechteckige Drilldowns durch die Hierarchie oder komplexere Treffertests durchführen, um z. B. transparente Bereiche in Ihrer Ansicht zu vermeiden, die Berührungen durch diese Teile zulassen. Wenn Sie einen Drilldown durchführen müssen, kann CGRectContainsPoint genauso verwendet werden, wie ich es verwendet habe, aber vergessen Sie nicht, Ihre Punkte für jede Ansichtsebene, in die Sie bohren, in lokale Ansichtskoordinaten zu versetzen.

Die Methode preventSelectionChange verhindert, dass meine benutzerdefinierte Annotation ausgewählt wird. Ich verwende sie als anpassbare / interaktive Callouts von Map-Pins. Dadurch bleibt der Pin, auf den sie sich bezieht, ausgewählt und die Auswahl nicht auf diese Annotation geändert .

    
jhabbott 27.12.2011, 22:29
quelle
1

Haben Sie MKAnnotationView von der Unterklasse abgeleitet oder haben Sie die Bildeigenschaft geändert?

Hier finden Sie die Dokumentation zum Festlegen der image -Eigenschaft.

  

Diskussion:   Durch Zuweisen eines neuen Bilds zu dieser Eigenschaft wird auch die Größe des Rahmens der Ansicht geändert, sodass sie der Breite und Höhe des neuen Bilds entspricht. Die Position des Rahmens der Ansicht ändert sich nicht.

Überprüfen Sie die Größe des Rahmens Ihrer Anmerkungsansicht, an der Ihr Objekt Berührungen erhalten kann.

    
Rich86man 27.12.2011 20:29
quelle
0

Ich habe etwas Ähnliches wie folgt implementiert:

  1. Erstellen Sie eine Unterklasse der Gesture Recognizer-Klasse, die Berührungen
  2. behandelt
  3. Erstellen Sie eine Unterklasse der UIImage-Klasse, diese Klasse verwendet die recognizer-Klasse, um Ihre Gesten zu verarbeiten
  4. Verwenden Sie dies in der Anmerkung

Die Gestenerkenner-Unterklasse verarbeitet Ihre Gesten, wenn Sie sie an einer beliebigen Stelle im Bild ausführen. Dies sollte dir helfen.

Halten Sie uns auf dem Laufenden, ob diese Lösung für Sie funktioniert hat ...

    
TheGhostWhoWalks 27.12.2011 19:25
quelle
0

@jhabbott Lösung hat nie für mich funktioniert, wie ich hier erwähnt habe.

Ich habe ein Bild und ein Etikett nebeneinander. Das Bild wurde angezeigt, indem Sie die Eigenschaft "anotationview image " und die Bezeichnung festlegen, indem Sie UILabel

hinzufügen

Ich habe die Methode func point(inside:with:) auf die UILabel one umgeleitet (die die Bildzone enthielt) und hitTest hat genau dieselbe Ansicht zurückgegeben, egal ob ich auf die Beschriftung oder das Bild geklickt habe. Der Label-Klick hat jedoch keinen Callback erzeugt ...

Schließlich habe ich den MKAnnotationView-Rahmen vergrößert, um Label + Bild einzufügen, ich habe annotationView.image auf nil gesetzt und ich habe meine benutzerdefinierte UIImageView erstellt.

Da ich den Ankerpunkt in der Mitte des Bildes haben wollte, musste ich einen benutzerdefinierten festlegen:

%Vor%

Dann löschte ich point(inside:with:) und hitTest(point:with:) Überschreibungen, die nichts getan haben.

Und jetzt, zum ersten Mal, ist meine Anmerkungsansicht vollständig reaktiv.

    
Martin 19.09.2017 10:11
quelle