Gibt es eine Möglichkeit festzustellen, ob ein MKMapView herumgeschleppt wurde?
Ich möchte den zentralen Standort jedes Mal ermitteln, wenn ein Benutzer die Karte mit zieht, CLLocationCoordinate2D centre = [locationMap centerCoordinate];
aber ich benötige eine Delegierungsmethode oder etwas, das ausgelöst wird, sobald der Benutzer mit der Karte navigiert.
Danke im Voraus
- (void)mapView:(MKMapView *)mapView regionWillChangeAnimated:(BOOL)animated
hat den Job gemacht.Der Code in der akzeptierten Antwort wird ausgelöst, wenn die Region aus irgendeinem Grund geändert wird. Um einen Kartenzug richtig zu erkennen, müssen Sie einen UIPanGestureRecognizer hinzufügen. Übrigens ist dies die Erkennung von Drag-Gesten (Schwenken = Ziehen).
Schritt 1: Fügen Sie den Gestenerkenner in viewDidLoad hinzu:
Schritt 2: Fügen Sie das Protokoll UIGestureRecognizerDelegate zum Ansichtscontroller hinzu, damit es als Delegat fungiert.
Schritt 3: Fügen Sie den folgenden Code für den UIPanGestureRecognizer hinzu, um mit den bereits vorhandenen Gestenerkennern in MKMapView zu arbeiten:
Schritt 4: Wenn Sie Ihre Methode einmal statt 50 Mal pro Drag aufrufen möchten, erkennen Sie den Status "Drag beendet" in Ihrer Auswahl:
quelle
UIPinchGestureRecognizer
als auchreadyForUpdate
, und dieses Flag dann eingecheckt- (void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated
.Dies ist die einzige für mich funktionierende Methode, die vom Benutzer initiierte Schwenk- und Zoomänderungen erkennt:
quelle
MKMapView
in iOS abhängt . Diese Implementierung kann sich in jedem iOS-Update ändern, da es nicht Teil der API ist.(Nur die) Schnelle Version von @mobis hervorragender Lösung :
quelle
self.mapView.subviews[0]
umself.mapView.subviews[0] as! UIView
self.map.delegate = self
zum Laufen zu bringen, musste ich zu viewDidLoadSwift 3-Lösung für Janos Antwort oben:
Fügen Sie das Protokoll UIGestureRecognizerDelegate zu Ihrem ViewController hinzu
Erstellen Sie den UIPanGestureRecognizer in
viewDidLoad
und setzen Sie ihndelegate
auf selfFügen Sie eine Protokollmethode hinzu, damit Ihre Gestenerkennung mit den vorhandenen MKMapView-Gesten funktioniert
Fügen Sie in Ihrer Schwenkgeste die Methode hinzu, die vom Selektor aufgerufen wird
quelle
Nach meiner Erfahrung, ähnlich wie "Suchen während des Tippens", fand ich, dass ein Timer die zuverlässigste Lösung ist. Es müssen keine zusätzlichen Gestenerkenner zum Schwenken, Kneifen, Drehen, Antippen, Doppeltippen usw. hinzugefügt werden.
Die Lösung ist einfach:
Wenn der Timer ausgelöst wird, laden Sie Markierungen für die neue Region
quelle
Eine andere mögliche Lösung besteht darin, touchMoved: (oder touchEnded: usw.) in den Ansichts-Controller zu implementieren, der Ihre Kartenansicht enthält, wie folgt:
Dies kann in einigen Fällen einfacher sein als die Verwendung von Gestenerkennern.
quelle
Sie können Ihrer Karte im Interface Builder auch eine Gestenerkennung hinzufügen. Verbinde es mit einer Steckdose für seine Aktion in deinem viewController, ich habe meine "mapDrag" genannt ...
Dann machen Sie so etwas in der .m: Ihres viewController:
Stellen Sie sicher, dass Sie dies auch dort haben:
Natürlich müssen Sie Ihren viewController zu einem UIGestureRecognizerDelegate in Ihrer .h-Datei machen, damit dies funktioniert.
Andernfalls ist der Responder der Karte der einzige, der das Gestenereignis hört.
quelle
UIGestureRecognizerStateBegan
So erkennen Sie, wann eine Geste in der Kartenansicht beendet wurde:
[ https://web.archive.org/web/20150215221143/http://b2cloud.com.au/tutorial/mkmapview-determining-whether-region-change-is-from-user-interaction/ )
Dies ist sehr nützlich, um eine Datenbankabfrage erst durchzuführen, nachdem der Benutzer die Karte gezoomt / gedreht / gezogen hat.
Für mich wurde die regionDidChangeAnimated-Methode erst aufgerufen, nachdem die Geste ausgeführt wurde, und wurde beim Ziehen / Zoomen / Drehen nicht oft aufgerufen. Es ist jedoch hilfreich zu wissen, ob dies auf eine Geste zurückzuführen ist oder nicht.
quelle
Viele dieser Lösungen sind auf der hackigen / nicht der von Swift beabsichtigten Seite, daher habe ich mich für eine sauberere Lösung entschieden.
Ich unterteile MKMapView einfach und überschreibe touchMoved. Obwohl dieses Snippet es nicht enthält, würde ich empfehlen, einen Delegaten oder eine Benachrichtigung zu erstellen, um die gewünschten Informationen über die Bewegung weiterzuleiten.
Sie müssen die Klasse in Ihren Storyboard-Dateien aktualisieren, um auf diese Unterklasse zu verweisen, und alle Karten ändern, die Sie auf andere Weise erstellen.
Wie in den Kommentaren erwähnt, rät Apple von der Verwendung von Unterklassen ab
MKMapView
. Obwohl dies im Ermessen des Entwicklers liegt, ändert diese spezielle Verwendung das Verhalten der Karte nicht und funktioniert seit über drei Jahren ohne Zwischenfälle für mich. Allerdings ist Vergangenheit erzielte Ergebnisse nicht zeigen zukünftige Kompatibilität, so Ausschluss jeder Haftung .quelle
Janos Antwort hat bei mir funktioniert, daher dachte ich, ich würde eine aktualisierte Version für Swift 4 / XCode 9 hinterlassen, da ich Ziel C nicht besonders gut beherrsche und ich bin sicher, dass es einige andere gibt, die dies auch nicht sind.
Schritt 1: Fügen Sie diesen Code in viewDidLoad hinzu:
Schritt 2: Stellen Sie sicher, dass Ihre Klasse dem UIGestureRecognizerDelegate entspricht:
Schritt 3: Fügen Sie die folgende Funktion hinzu, um sicherzustellen, dass Ihre panGesture gleichzeitig mit anderen Gesten funktioniert:
Schritt 4: Und stellen Sie sicher, dass Ihre Methode nicht "50 Mal pro Drag" genannt wird, wie Jano zu Recht betont:
* Beachten Sie das Hinzufügen von @objc im letzten Schritt. XCode erzwingt dieses Präfix für Ihre Funktion, damit es kompiliert werden kann.
quelle
Sie können nach animierten Eigenschaften suchen, wenn diese falsch sind, und dann die vom Benutzer gezogene Karte
quelle
Ich habe versucht, eine Anmerkung in der Mitte der Karte zu haben, die sich immer in der Mitte der Karte befindet, unabhängig davon, was die Verwendung bewirkt. Ich habe mehrere der oben genannten Ansätze ausprobiert, und keiner von ihnen war gut genug. Ich fand schließlich einen sehr einfachen Weg, dies zu lösen, indem ich mich an die Antwort von Anna anlehnte und sie mit Enekos Antwort kombinierte. Grundsätzlich wird regionWillChangeAnimated als Beginn eines Ziehens und regionDidChangeAnimated als Ende eines Ziehvorgangs behandelt und der Pin mithilfe eines Timers in Echtzeit aktualisiert:
quelle
Ich weiß, dass dies ein alter Beitrag ist, aber hier mein Swift 4/5-Code von Janos Antwort mit Pan- und Pinch-Gesten.
Genießen!
quelle
Code hier eingebenIch habe es geschafft, dies auf einfachste Weise zu implementieren, die alle Interaktionen mit der Karte handhabt (Tippen / Doppel / N Tippen mit 1/2 / N Fingern, Schwenken mit 1/2 / N Fingern, Kneifen und Drehen
gesture recognizer
Sie den Container der Kartenansicht und fügen Sie ihn hinzugesture recognizer's
delegate
ein Objekt setzen, das implementiert wirdUIGestureRecognizerDelegate
gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch)
Methode implementierenquelle
Erstens , stellen Sie sicher , dass Ihre aktuellen View - Controller ein Delegierter der Karte ist. Stellen Sie Ihren Map View-Delegaten auf self ein und fügen Sie ihn
MKMapViewDelegate
Ihrem View Controller hinzu. Beispiel unten.Und fügen Sie dies Ihrer Kartenansicht hinzu
Zweitens fügen Sie diese Funktion hinzu, die ausgelöst wird, wenn die Karte verschoben wird. Es filtert alle Animationen heraus und wird nur ausgelöst, wenn mit ihnen interagiert wird.
quelle