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

Dan*_*eny 70 iphone mkmapview

随着MKMapView有一个名为"显示用户的当前位置",它会自动显示在一个用户位置的选项map.

当它被找到时(如果它发生变化)我想移动并缩放到这个位置.

问题是,当用户位置更新时,似乎没有任何方法被调用map,所以我无处可放置代码zoom/scroll.

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

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

ddn*_*dnv 106

您必须注册KVO的userLocation.location财产通知MKMapView.

为此,请将此代码放在viewDidLoad:ViewController中或初始化地图视图的位置.

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

然后实现此方法以接收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
    }
}
Run Code Online (Sandbox Code Playgroud)

这段代码对我来说很好.
BTW,self是我在此上下文中的ViewController.

  • 对于那些对如何实施感到困惑的人:[self moveOrZoomOrAnythingElse]; 只需在此链接添加类别:http://troybrant.net/blog/2010/01/set-the-zoom-level-of-an-mkmapview/到您的代码然后替换行:[self moveOrZoomOrAnythingElse]; with [self.mapView setCenterCoordinate:self.mapView.userLocation.location.coordinate zoomLevel:14 animated:YES]; 它就像一个魅力. (12认同)
  • 此代码中存在问题.仅当用户位置已经位于地图上可见区域的某个位置时,它才有效.[self.mapView isUserLocationVisible]仅在用户位置在当前地图区域内时才为true.相反,该行应为:self.mapView.showsUserLocation (6认同)

MrH*_*Hus 52

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

mapView是MKMapView*mapView的名称;

在viewDidLoad中添加此行,请注意加载中可能有更多行.这只是简化了.

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

然后创建将地图移动到当前位置的实际列表方法:

// 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];
}
Run Code Online (Sandbox Code Playgroud)

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

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


thi*_*sai 45

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

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

- (void)setUserTrackingMode:(MKUserTrackingMode)mode animated:(BOOL)animated;
Run Code Online (Sandbox Code Playgroud)

  • 很好的抓住.这样容易得多. (6认同)

yon*_*nel 13

您可以__CODE__通过实施__CODE__协议监视何时更新地图上的用户位置.刚实施:

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

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


Ken*_*ili 6

试试这个:

[mapView setUserTrackingMode:MKUserTrackingModeFollow animated:YES];
Run Code Online (Sandbox Code Playgroud)