92 Stimmen

feststellen, ob MKMapView gezogen/verschoben wurde

Gibt es eine Möglichkeit festzustellen, ob ein MKMapView herumgezogen wurde?

Ich möchte die zentrale Position jedes Mal, wenn ein Benutzer die Karte zieht mit CLLocationCoordinate2D centre = [locationMap centerCoordinate]; aber ich bräuchte eine Delegate-Methode oder etwas, das ausgelöst wird, sobald der Benutzer auf der Karte navigiert.

Vielen Dank im Voraus

8voto

Eneko Alonso Punkte 17508

Meiner Erfahrung nach ist, ähnlich wie bei der "Suche während des Tippens", ein Timer die zuverlässigste Lösung. Damit entfällt die Notwendigkeit, zusätzliche Gestenerkenner für das Schwenken, Auf- und Zuziehen, Drehen, Tippen, Doppeltippen usw. hinzuzufügen.

Die Lösung ist einfach:

  1. Wenn sich die Kartenregion ändert, den Timer setzen/zurücksetzen
  2. Wenn der Timer ausgelöst wird, werden Marker für die neue Region geladen.

    import MapKit
    
    class MyViewController: MKMapViewDelegate {
    
        @IBOutlet var mapView: MKMapView!
        var mapRegionTimer: NSTimer?
    
        // MARK: MapView delegate
    
        func mapView(mapView: MKMapView, regionDidChangeAnimated animated: Bool) {
            setMapRegionTimer()
        }
    
        func setMapRegionTimer() {
            mapRegionTimer?.invalidate()
            // Configure delay as bet fits your application
            mapRegionTimer = NSTimer.scheduledTimerWithTimeInterval(1.0, target: self, selector: "mapRegionTimerFired:", userInfo: nil, repeats: false)
        }
    
        func mapRegionTimerFired(sender: AnyObject) {
            // Load markers for current region:
            //   mapView.centerCoordinate or mapView.region
        }
    
    }

8voto

CodeBender Punkte 33325

Viele dieser Lösungen sind eher hakelig bzw. nicht das, was Swift beabsichtigte, daher habe ich mich für eine sauberere Lösung entschieden.

Ich unterstelle einfach MKMapView und überschreibe touchesMoved. Während dieses Snippet nicht enthalten ist, würde ich empfehlen, einen Delegaten oder eine Benachrichtigung zu erstellen, um die gewünschten Informationen über die Bewegung weiterzugeben.

import MapKit

class MapView: MKMapView {
    override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
        super.touchesMoved(touches, with: event)

        print("Something moved")
    }
}

Sie müssen die Klasse in Ihren Storyboard-Dateien aktualisieren, um auf diese Unterklasse zu verweisen, und alle Maps, die Sie auf andere Weise erstellen, ändern.

Wie in den Kommentaren erwähnt, Apple entmutigt die Verwendung der Unterklassenbildung MKMapView . Obwohl dies im Ermessen des Entwicklers liegt, ändert diese spezielle Verwendung das Verhalten der Karte nicht und funktioniert bei mir seit über drei Jahren ohne Zwischenfälle. Allerdings sagt die bisherige Leistung nichts über die zukünftige Kompatibilität aus. Ausschluss der Gewährleistung .

7voto

Aaron Punkte 188

Eine andere mögliche Lösung ist die Implementierung von touchesMoved: (oder touchesEnded:, etc.) im View-Controller, der Ihre Kartenansicht enthält, wie folgt:

-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
    [super touchesMoved:touches withEvent:event];

    for (UITouch * touch in touches) {
        CGPoint loc = [touch locationInView:self.mapView];
        if ([self.mapView pointInside:loc withEvent:event]) {
            #do whatever you need to do
            break;
        }
    }
}

Dies kann in manchen Fällen einfacher sein als die Verwendung von Gestenerkennern.

6voto

CommaToast Punkte 10365

Sie können Ihrer Karte im Interface Builder auch einen Gestenerkenner hinzufügen. Verknüpfen Sie es bis zu einem Ausgang für seine Aktion in Ihrem viewController, ich nannte meine "mapDrag"...

Dann werden Sie etwas wie dieses in Ihrem viewController's .m tun:

- (IBAction)mapDrag:(UIPanGestureRecognizer *)sender {
    if(sender.state == UIGestureRecognizerStateBegan){
        NSLog(@"drag started");
    }
}

Vergewissern Sie sich, dass Sie dies auch dort haben:

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {
    return YES;
}

Natürlich müssen Sie Ihre viewController ein UIGestureRecognizerDelegate in Ihrer .h-Datei zu machen, damit das zu arbeiten.

Andernfalls ist der Antwortgeber der Karte der Einzige, der das Gestenereignis hört.

5voto

Doug Voss Punkte 964

Um zu erkennen, wann eine Geste auf 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 dann durchzuführen, wenn der Benutzer mit dem Zoomen/Drehen/Ziehen der Karte fertig ist.

Bei mir wurde die regionDidChangeAnimated-Methode nur aufgerufen, nachdem die Geste ausgeführt wurde, und wurde beim Ziehen/Zoomen/Drehen nicht oft aufgerufen, aber es ist nützlich zu wissen, ob dies auf eine Geste zurückzuführen ist oder nicht.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X