2009-09-17 8 views
19

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

編集:

それはMKMapViewを上書きし、他のLocationManagerを使用することは可能ですか?お使いのコントローラで

答えて

42

はい、別のロケーションマネージャオブジェクトを持ち、その値をマップビューに割り当てることができます(BTW、SOコードフォーマッタのボルキングを防ぐために、リストプレフィックスとして '='を使用しています)。

=あなたのUIViewControllerでは、1つはMKMapViewに、もう1つはCLLocationManagerです。

= MKMapViewと他のウィンドウクロムでXIBファイルを作成します。コンセントをコントローラのプロペティに接続します。 MKMapViewがユーザーの場所に従わないようにしてください。

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

= viewControllerのloadViewメソッドでは、MKMapViewのNIBをロードします。ユーザーからのフィードバックを得るには、UIActivityIndicatorViewスピナーを入れてstartAnimatingに設定するとよいでしょう。イベントは、最後のN秒以降に更新されたかどうかを確認するためにlocationManager:didUpdateToLocation:fromLocation:チェックで=

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

:次に、あなたが開始します。その後、更新を停止するように位置管理プログラムに指示し、アニメーションを停止するスピナーを取得し、緯度/経度データを取得し、ビュースパンおよび領域と共にマップビューに割り当てて、ズームして正しい場所に配置します。

=今ここでは難しい部分があります。青い大理石のスロボは、ユーザーの位置を追跡するmapviewの機能です。あなたは、現実のものがキックインするまで(または、現在の位置に別のマーカーを使用して、自分自身の位置を維持するまで)、一時的に「偽造」する必要があります。個人的に私は、ユーザーがよく知っている青い大理石と一緒に行くだろう。

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

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

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

= observeValueForKeyPathを実装します。更新はのviewDidLoadに追加するのMapView自身userLocationをできるように

=。

-(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のuserlocationlocation属性が値を持っているときに呼び出されます離れていない(それは少しメモリホッグですが、もしあなたがそれをリリースすれば、MapViewがタイルをロードして行く準備が整うまでもう一度待たなければなりません)。

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

= viewControllerのviewWillDisappearメソッドを実装し、mapviewで手動でuserLocationのトラッキングをオフにして、次回のビューの表示時にデフォルトでオフにしたい場合があります。あなたはまた、最後に知られているuserLocationを取得し、次の行進のためにそれを保存したいと思うでしょう。そうすれば、viewWillAppearメソッドでマーカーのジャグリングをすべて行うことができ、準備が整うまでuserLocationが心配する必要はありません。

幸運。

+1

ラミンに感謝します。これは予想される解決策ではありませんが、私はそれが最も近い既存の解決策だと思います。 – jantimon

+0

はい、マップビュー上のuserLocationを初期値に設定することができればもっと簡単になりました...または独自のCLLocationManagerインスタンスを作成する代わりに既存のCLLocationManagerインスタンスを使用できるようにすることは...しかし残念ながら、 t。 – Ramin

27

:マップが表示されたら

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

初期にfalseにshowUserLocationプロパティを設定してみてください、その後、マップビューが以前持っていたregionを復元パロアルトに近い中心にすることが

+0

私が必要とするものではありません。私は青の位置インジケータ( "現在の場所")の位置を変更したい。 – jantimon

+1

userLocationはreadonlyプロパティですが、あなたはそれについて何かできるとは思っていません。唯一の合法的な方法は、アップルが提供し青いインジケータを無効にすることである。これは無意味である。 – zakovyrya

+1

500m x 500mの地域を設定する[mapView setRegion:MKCoordinateRegionMakeWithDistance(CLLocationCoordinate2Make(54.233498f、1.99375f)、500,500) ]; –

0

を起こっています(前のマップが破壊される前に、これを格納しておく必要があります)。

これはあなたが望むものですか?

+0

いいえリージョンについてではなく位置インジケータについて – jantimon

0

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

リモートコントロールカーとのソケット接続があり、ペイロードにジオロケーション情報を含むソケットデータを返すとします。それを解析し、地図上のサムネイルの位置をリアルタイムで更新することができます。そのためには "userLocation"プロパティは必要ありませんが、必要に応じて表示することができます。

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

+0

新しいMKMapViewが表示されている間、最初の10秒間ユーザーの位置が表示されないか間違って表示されることがあります。これらの10秒後にすべてが問題ありません。しかし、私がポジションを知っているので、私はそれらの10秒をスキップしたいです。 – jantimon

+1

は多分古いかもしれませんが、誰かがこれを読んだら、あなたはユーザーを見つけるためにGPSを起動するアプリケーションを起動するときにユーザーの場所を取得する必要があります。そのようにして、ユーザーが地図を開くときには、すでにその場所にいることになります。 PS:それは10秒間かなり正常です、あなたが場所をオンにした後、Googleマップのアプリケーションでさえ数秒かかります – renevdkooi

関連する問題