MKMapView
有一个名为“显示用户当前位置”的选项,该选项会自动显示map
上的用户位置。
我想在找到它时移动并缩放到这个位置(如果它发生了变化)。
问题是,在map
上更新用户位置时,似乎没有调用任何方法,因此我无处可放置zoom/scroll
的代码。
当MKMapView
获得(或更新)用户位置以便我可以移动/缩放它时,是否有通知方法?如果我使用自己的CLLocationManager
更新,我得到的更新与地图上用户标记的更新不符,所以当我的地图移动并在蓝色图钉出现之前缩放几秒时,它看起来很傻。
这感觉就像基本功能一样,但我花了几周的时间寻找解决方案而不是近距离接触。
答案 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