2010-03-18 35 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]; 
相关问题