wake-up-neo.com

Wie initialisiere ich MKMapView mit einem bestimmten Benutzerstandort?

Meine App kennt die aktuelle Benutzerposition (CoreLocation.framework). Sobald der Benutzer eine neue MapView öffnet, sucht sein iPhone erneut nach der aktuellen Position. Ist es möglich, dies zu überspringen oder die erste Benutzerposition für mkMapView zu ändern?

Bearbeiten:

Ist es möglich, MKMapView zu überschreiben und einen anderen LocationManager zu verwenden?

19
jantimon

Ja, es ist möglich, über ein separates Standortmanagerobjekt zu verfügen und dessen Wert der Kartenansicht zuzuweisen (Übrigens, ich verwende '=' als Listenpräfix, um zu verhindern, dass der SO-Code-Formatter verfälscht wird).

= In Ihrem UIViewController pflegen Sie zwei separate Eigenschaften: eine für eine MKMapView und eine für eine CLLocationManager

= Erstellen Sie eine XIB-Datei mit MKMapView und einem beliebigen anderen Fensterchrom. Verbinden Sie die Auslässe mit den Controller-Eigenschaften. Stellen Sie sicher, dass MKMapView dem Benutzerort NICHT folgt.

= Lassen Sie den UIViewController das CLLocationManagerDelegate-Protokoll implementieren - insbesondere die locationManager:didUpdateToLocation:fromLocation:-Methode, die aufgerufen wird, wenn ein neuer Standortwert verfügbar ist. Wir stellen den Controller als Delegierten für den Standortmanager ein.

= Laden Sie in der loadView-Methode des ViewControllers die NIB mit der MKMapView-Datei. Um dem Benutzer Feedback zu geben, können Sie einen UIActivityIndicatorView-Spinner einrichten und auf startAnimating setzen. Dann fängst du an mit:

self.locationManager = [[CLLocationManager alloc] init];
self.locationManager.delegate = self;
self.locationManager.desiredAccuracy = kCLLocationAccuracyKilometer;
self.locationManager.distanceFilter = 10; // or whatever
[self.locationManager startUpdatingLocation];

= Überprüfen Sie in locationManager:didUpdateToLocation:fromLocation:, ob das Ereignis seit den letzten N Sekunden aktualisiert wurde. Dann fordern Sie den Standortmanager auf, die Aktualisierung abzubrechen, den Drehbeschleuniger anzuhalten, die Animation zu beenden, die Lat/Long-Daten abzurufen und sie der Kartenansicht zusammen mit einer Ansichtsspanne und einem Bereich zuzuordnen, damit sie zoomt und an den richtigen Ort zentriert.

= Hier ist der knifflige Teil: Der "Throbber" aus blauem Marmor ist eine Funktion des Standortes des Mapview-Tracking-Benutzers. Sie müssen es vorübergehend "fälschen", bis der echte eintrifft (oder verwenden Sie einfach einen separaten Marker für den aktuellen Standort und behalten Sie seine Position selbst bei). Persönlich würde ich mit dem blauen Marmor gehen, den der Benutzer kennt. 

= Damit es beim Start angezeigt wird, müssen Sie eine benutzerdefinierte MKAnnotationView mit der blauen Marmorgrafik erstellen, die an der vom Standortmanager zurückgegebenen Position hinzugefügt wird. Dies bedeutet, dass Sie einen Schnappschuss von einer Kartenansicht mit der angezeigten Position erstellen, dann nur die blaue Murmel herausnehmen und als Bild für eine benutzerdefinierte Anmerkungsansicht verwenden.

= Wenn Sie möchten, dass die Karte aktiv verfolgt wird, können Sie die Benutzerlokalisierung der Kartenansicht aktivieren. Wenn die tatsächlichen Daten abgerufen werden, blenden Sie die zuvor gesetzte Markierung aus und lassen die Aktualisierung die Kartenansicht übernehmen. Die andere Option besteht darin, dem vorhandenen Standortmanager zu gestatten, weiterhin jede Sekunde Aktualisierungen zu erhalten und die Position der blauen Marmoranmerkungen selbst zu aktualisieren.

= Um zuzulassen, dass der mapview-eigene userLocation die Aktualisierung zu viewDidLoad hinzufügt:

[self.map.userLocation addObserver:self 
forKeyPath:@"location" 
options:(NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld) 
context:NULL];
self.map.showsUserLocation = YES; // starts updating user location

= Implementiere observeValueForKeyPath. Es wird aufgerufen, wenn das location-Attribut des userlocation des Mapview einen Wert hat:

-(void)observeValueForKeyPath:(NSString *)keyPath 
      ofObject:(id)object 
        change:(NSDictionary *)change 
       context:(void *)context 
{
     if ([self.map isUserLocationVisible]) {
         [self.locationManager stopUpdatingLocation];
         self.ownBlueMarble.hidden = YES;
     }
     // The current location is in self.map.userLocation.coordinate
}

= Um die Aufwärmverzögerung beim Anzeigen des aktuellen Standorts zu vermeiden, halten Sie einen Verweis auf den viewController, der die Karte und den Standortmanager enthält, so dass er nicht verschwindet (es ist ein bisschen wie ein Arbeitsspeicher, aber wenn Sie ihn freigeben, haben Sie dies erneut warten, bis MapView die Kacheln lädt und einsatzbereit ist). 

= In viewWillLoad können Sie den letzten bekannten Speicherort in die benutzerdefinierte Bluemarble-Annotation einfügen und anzeigen. Schalten Sie das userLocation-Tracking ein bzw. aus und wenn Sie die Benachrichtigung erhalten, funktioniert der gleiche Trick zum Ausblenden der Annotation-Show-the-Real-Marmor. Der eigene Positionsmanager von mapview greift ein, und wenn er die Daten hat, können Sie Ihre Anmerkungsmarkierung verschwinden lassen.

= Möglicherweise möchten Sie die viewWillDisappear-Methode von viewController implementieren und die userLocation-Verfolgung manuell in der Kartenansicht deaktivieren, sodass diese standardmäßig deaktiviert ist, wenn die Ansicht das nächste Mal aufgerufen wird. Sie möchten auch das letzte bekannte userLocation erhalten und es für den nächsten Schritt speichern. Auf diese Weise können Sie alle Positionsmarkierungs-Jonglieren mit der viewWillAppear-Methode ausführen und müssen sich keine Sorgen über die Benutzerlokation machen, bis Sie dazu bereit sind.

Viel Glück.

42
Ramin

In Ihrem Controller:

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    CLLocationCoordinate2D coord = {latitude: 37.423617, longitude: -122.220154};
    MKCoordinateSpan span = {latitudeDelta: 1, longitudeDelta: 1};
    MKCoordinateRegion region = {coord, span};
    [mapView setRegion:region];
}

Wenn eine Karte erscheint, wird sie in der Nähe von Palo Alto zentriert

27
zakovyrya

Sie müssen keinen anderen Standort-Manager verwenden. Sie können beliebige Punkte zur Karte hinzufügen und diese über eine beliebige andere Logik aktualisieren.

Angenommen, Sie hatten eine Socket-Verbindung zu einem Fernsteuerungsauto und dieses Auto sendet Socket-Daten mit Geo-Positionsinformationen in der Nutzlast zurück. Sie könnten dies analysieren und den Ort des Miniaturbilds auf Ihrer Karte in Echtzeit aktualisieren. Die "userLocation" -Eigenschaft wird dafür nicht benötigt, Sie können sie jedoch anzeigen, wenn Sie möchten.

Der Standort des Benutzers ist schreibgeschützt. Sie können ihn verwenden oder nicht. Das bedeutet nicht, dass Sie einen anderen Standortmanager benötigen, um alles zu tun, was Sie möglicherweise tun müssen. Das klingt so, als würde Ihre App diese Funktion nicht wirklich benötigen, aber ich könnte Ihre Frage missverstehen.

0
slf

Setzen Sie die showUserLocation-Eigenschaft bei der Initialisierung auf false, und stellen Sie dann die region wieder her, die die Kartenansicht zuvor hatte (Sie müssen diese natürlich speichern, bevor die vorherige Karte zerstört wird).

Wolltest du das?

0
Nick Bedford