web-dev-qa-db-ja.com

特定のユーザーの場所でMKMapViewを初期化する方法

私のアプリは現在のユーザーの位置(CoreLocation.framework)を知っています。ユーザーが新しいMapViewを開くとすぐに、iPhoneは現在の位置の検索を再開します。それをスキップしたり、mkMapViewの最初のユーザーの位置を変更したりすることはできますか?

編集:

MKMapViewを上書きして他のLocationManagerを使用することは可能ですか?

19
jantimon

はい、別のロケーションマネージャーオブジェクトを使用して、その値をマップビューに割り当てることができます(BTW、SO code-formatter fromボーキング)。

= UIViewControllerでは、2つの異なるプロパティを維持します。1つはMKMapViewに対するもので、もう1つはCLLocationManagerに対するものです。

= MKMapViewとその他のウィンドウを使用してXIBファイルを作成chrome必要です。アウトレットをコントローラープロパティに接続します。MKMapViewがユーザーをフォローしていないことを確認してくださいロケーション。

= UIViewControllerにCLLocationManagerDelegateプロトコルを実装させます。特に、新しい場所の値が利用可能になるたびに呼び出されるlocationManager:didUpdateToLocation:fromLocation:メソッドを実装します。コントローラーをロケーションマネージャーのデリゲートとして設定します。

= viewControllerのloadViewメソッドで、MKMapViewを含むNIBをロードします。ユーザーにフィードバックを与えるには、UIActivityIndicatorViewスピナーを付けてstartAnimatingに設定します。次に、次のことから始めます。

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

= locationManager:didUpdateToLocation:fromLocation:で、最後のN秒以降にイベントが更新されたかどうかを確認します。次に、ロケーションマネージャーに更新を停止し、スピナーでアニメーションを停止し、緯度/経度データを取得して、ビュースパンとリージョンとともにマップビューに割り当て、適切な場所にズームおよびセンタリングするように指示します。

=ここで注意が必要な部分があります。青い大理石の「throbber」は、ユーザーの位置を追跡するマップビューの機能です。あなたは本物が発動するまで一時的に「偽物」にする必要があります(または現在の場所に別のマーカーを使用して、自分の位置を自分で維持します)。個人的には、ユーザーがよく知っている青い大理石を使います。

=起動時に正しく表示されるようにするには、ロケーションマネージャーによって返された場所に追加された青い大理石のグラフィックのみを含むカスタムMKAnnotationViewを作成する必要があります。これは、位置を示すマップビューのスナップショットを撮り、青い大理石だけをフォトショッピングして、カスタムアノテーションビューの画像として使用することを意味します。

=マップをアクティブに追跡したい場合は、マップビューのユーザー位置追跡を有効にして、実際のデータを取得したら、以前に設定したマーカーを非表示にして、マップビューに更新を行わせることができます。もう1つのオプションは、既存のロケーションマネージャーが毎秒更新を受信し続け、青い大理石の注釈の位置を自分で更新できるようにすることです。

= mapviewの独自のuserLocationに更新を追加して、viewDidLoadに追加します。

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

= observeValueForKeyPathを実装します。マップビューのlocationuserlocation属性に値があると呼び出されます。

-(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
}

=現在の場所を表示する際のウォームアップの遅延を回避するために、マップとロケーションマネージャを含むviewControllerへの参照を保持して、マップが消えないようにします(少しメモリを消費しますが、解放すると、 MapViewがタイルをロードして準備ができるまで再び待機します)。

= viewWillLoadでは、最後の既知の場所をカスタムブルーマーブルアノテーションに埋め込んで表示できます。 userLocationトラッキングのオンとオフを切り替えます。通知を受け取ったときに、同じ非表示の表示、実際の大理石のトリックが機能します。マップビュー独自のロケーションマネージャーが起動し、データがある場合は、アノテーションマーカーを非表示にすることができます。

= viewControllerのviewWillDisappearメソッドを実装し、マップビューのuserLocationトラッキングを手動でオフにして、次にビューが表示されたときにデフォルトでオフにすることができます。また、最後の既知のuserLocationを取得して、次の取得のために保存することもできます。そうすれば、viewWillAppearメソッドですべての位置決めマーカーの調整を行うことができ、準備ができるまでuserLocationが干渉することを心配する必要はありません。

幸運を。

42
Ramin

コントローラで:

- (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];
}

地図が表示されると、パロアルトの近くに配置されます

27
zakovyrya

別のロケーションマネージャーを使用する必要はありません。マップに必要なポイントを追加し、他のロジックを使用してそれらを更新できます。

リモートコントロール車へのソケット接続があり、その車がペイロードに地理位置情報を含むソケットデータを送り返したとします。それを解析して、マップ上のサムネイルの場所をリアルタイムで更新できます。これには「userLocation」プロパティは必要ありませんが、必要に応じて表示できます。

ユーザーの場所は読み取り専用であり、使用してもしなくてもかまいません。それはあなたがする必要があるかもしれない何かをするためにあなたが別のロケーションマネージャーを必要とするという意味ではありません。アプリにはその機能は本当に必要ないようですが、私はあなたの質問を誤解している可能性があります。

0
slf

初期化時にshowUserLocationプロパティをfalseに設定してから、以前にマップビューにあったregionを復元してみてください(前のマップが破棄される前に、これを保存する必要があります)。

これでよろしいですか?

0
Nick Bedford