如何在没有CLLocationManager的情况下将MKMapView缩放到用户当前位置?

时间:2010-03-18 22:13:05

标签: iphone mkmapview

MKMapView有一个名为“显示用户当前位置”的选项,该选项会自动显示map上的用户位置。

我想在找到它时移动并缩放到这个位置(如果它发生了变化)。

问题是,在map上更新用户位置时,似乎没有调用任何方法,因此我无处可放置zoom/scroll的代码。

MKMapView获得(或更新)用户位置以便我可以移动/缩放它时,是否有通知方法?如果我使用自己的CLLocationManager更新,我得到的更新与地图上用户标记的更新不符,所以当我的地图移动并在蓝色图钉出现之前缩放几秒时,它看起来很傻。

这感觉就像基本功能一样,但我花了几周的时间寻找解决方案而不是近距离接触。

6 个答案:

答案 0 :(得分:106)

您必须注册userLocation.location MKMapView viewDidLoad:属性的KVO通知。

要执行此操作,请将此代码放在ViewController的[self.mapView.userLocation addObserver:self forKeyPath:@"location" options:(NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld) context:NULL]; 中或初始化地图视图的位置。

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

然后实现此方法以接收KVO通知

self

此代码适用于我。
顺便说一句,在这种情况下,{{1}}是我的ViewController。

答案 1 :(得分:52)

这是ddnv和Dustin的回答的组合,对我有用:

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

不要忘记正确释放并取消注册观察者:

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

答案 2 :(得分:45)

自从iOS 5.0 Apple向MKMapView添加了一个新方法。这种方法完全符合您的要求和更多。

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

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

答案 3 :(得分:13)

您可以通过实施MKMapView协议监控MKMapViewDelegate何时更新地图上的用户位置。只需实施:

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

此回调应与地图上显示的内容完全同步。

答案 4 :(得分:6)

试试这个:

[mapView setUserTrackingMode:MKUserTrackingModeFollow animated:YES];

答案 5 :(得分:1)

没问题...在你的UIViewController子类的viewDidLoad方法中,有MKMapView添加它(假设你的MKMapView被命名为map):

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