2010-03-18 26 views
68

隨着MKMapView有一個選項稱爲「顯示用戶當前位置」,它會自動顯示用戶在map上的位置。如何在沒有CLLocationManager的情況下將MKMapView縮放到用戶當前位置?

我想移動並放大到找到該位置(如果它發生變化)。

問題是,當用戶位置在map上更新時,似乎沒有任何方法調用,所以我無處放置代碼將會zoom/scroll

MKMapView已獲得(或更新)用戶位置以便我可以移動/縮放它時,是否有方法可以通知?如果我使用我自己的CLLocationManager,我得到的更新與地圖上用戶標記的更新不符,所以當我的地圖在出現藍色引腳之前移動並放大幾秒時,看起來很愚蠢。

這感覺就像基本的功能,但我花了幾個星期尋找一個解決方案,沒有發現任何接近。

+0

我添加了一個CLLocationManager手動做到這一點,但在相同的時間甚至不火MapView繪製用戶位置,所以它看起來不起眼。 我不明白爲什麼這將是如此困難做 – 2010-03-20 10:14:21

回答

105

你必須爲userLocation.location財產的國際志願者組織登記的通知MKMapView

爲此,請將此代碼放置在ViewController的viewDidLoad:或您的地圖視圖初始化位置的任何位置。

[self.mapView.userLocation addObserver:self 
     forKeyPath:@"location" 
      options:(NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld) 
      context:NULL]; 

然後實現這個方法來接收KVO通知

- (void)observeValueForKeyPath:(NSString *)keyPath 
         ofObject:(id)object 
         change:(NSDictionary *)change 
         context:(void *)context { 

    if ([self.mapView showsUserLocation]) { 
     [self moveOrZoomOrAnythingElse]; 
     // and of course you can use here old and new location values 
    } 
} 

此代碼工作正常,我。
順便說一句,self是我在這個上下文中的ViewController。

+1

我以前從未使用過KVO,所以不得不使用Google。看起來這將完全符合我的需求 - 謝謝! – 2010-04-05 15:26:45

+6

此代碼存在問題。它只適用於用戶位置已經在地圖上可見的地方。 [self.mapView isUserLocationVisible]僅當用戶位置在當前地圖區域內時才爲真。相反,該行應閱讀:self.mapView.showsUserLocation – FelixLam 2010-06-04 09:20:14

+1

否則:謝謝你這個非常優雅的解決方案。 – FelixLam 2010-06-04 09:20:40

1

沒問題......你裏面UIViewController子類的viewDidLoad方法具有的MKMapView添加這個(假設你的MKMapView名爲地圖):

CLLocation *location = [[[CLLocation alloc] initWithLatitude:map.centerCoordinate.latitude longitude:map.centerCoordinate.longitude] autorelease]; //Get your location and create a CLLocation 
MKCoordinateRegion region; //create a region. No this is not a pointer 
region.center = location.coordinate; // set the region center to your current location 
MKCoordinateSpan span; // create a range of your view 
span.latitudeDelta = BASE_RADIUS/3; // span dimensions. I have BASE_RADIUS defined as 0.0144927536 which is equivalent to 1 mile 
span.longitudeDelta = BASE_RADIUS/3; // span dimensions 
region.span = span; // Set the region's span to the new span. 
[map setRegion:region animated:YES]; // to set the map to the newly created region 
+3

我試了很多這個,但問題似乎是這個代碼運行*之前*用戶的位置已確定。 – 2010-03-19 07:20:27

52

這是ddnv和達斯汀的答案,爲我工作的組合:

的MapView是的MKMapView * MapView的名稱;

在viewDidLoad中添加此行,請注意加載中可能有更多的行。這是 只是簡化。

- (void) viewDidLoad 
{ 
    [self.mapView.userLocation addObserver:self 
           forKeyPath:@"location" 
            options:(NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld) 
            context:nil]; 
} 

然後創建地圖移動到當前位置的實際上市方法:

// Listen to change in the userLocation 
-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context 
{  
    MKCoordinateRegion region; 
    region.center = self.mapView.userLocation.coordinate; 

    MKCoordinateSpan span; 
    span.latitudeDelta = 1; // Change these values to change the zoom 
    span.longitudeDelta = 1; 
    region.span = span; 

    [self.mapView setRegion:region animated:YES]; 
} 

不要忘記正確的dealloc和註銷觀察者:

- (void)dealloc 
{ 
    [self.mapView.userLocation removeObserver:self forKeyPath:@"location"]; 
    [self.mapView removeFromSuperview]; // release crashes app 
    self.mapView = nil; 
    [super dealloc]; 
} 
+0

我試過這個,但它崩潰了應用程序 – hanumanDev 2012-05-17 23:40:10

+0

不正確 - 你可以執行init/dealloc或viewDidLoad/viewDidUnload組合。可以在dealloc發生多次之前調用viewDidLoad - 第一次發生這種情況時,應用程序崩潰。 – joshis 2012-09-26 23:55:05

13

你可以通過實施MKMapViewDelegate協議來監視MKMapView何時更新地圖上的用戶位置。只需執行:

- (void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation  { 
    CLLocationAccuracy accuracy = userLocation.location.horizontalAccuracy; 
    if (accuracy ......) { 
    } 
} 

此回調應完全與地圖上顯示的內容同步。

43

由於iOS 5.0 Apple已經爲MKMapView添加了一個新方法。此方法完全符合您的要求和更多。

看看:https://developer.apple.com/documentation/mapkit/mkmapview

- (void)setUserTrackingMode:(MKUserTrackingMode)mode animated:(BOOL)animated; 
+6

好的。這很容易。 – 2012-06-18 20:07:19

+0

完美!爲我節省了時間。謝謝!! – tg2 2013-01-18 01:44:11

+0

這應該是iOS 5及更高版本所接受的答案。一行代碼:'[self.mapView setUserTrackingMode:MKUserTrackingModeFollow animated:YES];' – 2014-06-16 15:14:48

6

試試這個:

[mapView setUserTrackingMode:MKUserTrackingModeFollow animated:YES]; 
相關問題