防止 MKMapView 不断地重新缩放和重新居中到用户位置

Posted

技术标签:

【中文标题】防止 MKMapView 不断地重新缩放和重新居中到用户位置【英文标题】:Preventing MKMapView from continually re-zooming and re-centering to user location 【发布时间】:2011-11-23 07:49:39 【问题描述】:

我似乎与这里发布的许多关于MKMapView 的人有相反的问题。而不是不能让它放大并显示当前位置,我似乎无法让它 stop 这样做。以下是发生的事情:

我启动应用程序 MKMapView 用蓝点显示我的位置 我用手指在地图上拉远拉远 几秒钟后,MKMapView 突然重新放大到我当前位置的中心

我尝试将CLLocationManager 告诉stopUpdatingLocation(没有效果,因为MKMapView 知道如何使用CoreLocation),我尝试将MKMapView 告诉setShowsUserLocation:NO(没有完全显示蓝点,这不是我想要的)。我什至尝试删除我的CLLocationManager(无效)。这是什么原因造成的,我该如何阻止它?


是的,我确实在-loadView 中设置了位置管理器的准确度和距离。

我没有实现-mapViewDidFinishLoadingMap:。这是我的实现

-locationManager:didUpdateToLocation:fromLocation:
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation

    // How many seconds ago was this new location created?
    NSTimeInterval t = [[newLocation timestamp] timeIntervalSinceNow];

    // CLLocationManagers will return the last found location of the device first,
    // you don't want that data in this case. If this location was made more than 3
    // minutes ago, ignore it.
    if (t < -180)
    
        // This is cached data, you don't want it, keep looking
        return;
    

    [locationManager stopUpdatingLocation];

我认为这就是你要问的中心化问题,@Anna Karenina:

- (void)mapView:(MKMapView *)mv didUpdateUserLocation:(MKUserLocation *)u

    CLLocationCoordinate2D loc = [u coordinate];
    // Display the region 500 meters square around the current location
    MKCoordinateRegion region = MKCoordinateRegionMakeWithDistance(loc, 500, 500);
    [mv setRegion:region animated:YES];

【问题讨论】:

你在哪里做居中?在mapView:didUpdateUserLocation:?你能发布那个代码吗? 每次用户位置更改或获得新读数时,都会调用 didUpdateUserLocation 方法。您可以添加一个可以在方法中检查/设置的 bool ivar,以便只进行一次居中您可以根据 u.location.horizo​​ntalAccuracy 或 u.location.timestamp 有条件地居中。 好的,这是有道理的,但是......我现在有 -mapView:didUpdateUserLocation: 如果 u.location.horizo​​ntalAccuracy 是 > locationManager.desiredAccuracy ,则有条件地居中并且它仍在发生。如果我反转条件,我不会得到初始缩放。 记录 Horizo​​ntalAccuracy 和 desiredAccuracy 值以查看您得到的结果并相应地设置条件。第一个用户位置可能需要几秒钟才能出现。 我不应该将 u.location.horizo​​ntalAccuracy 与 locationManager.desiredAccuracy 进行比较,因为它始终为 -1。现在我正在与 50.0 进行比较。初始显示很好,但我仍然遇到问题。 【参考方案1】:

不要实现- (void)mapView:(MKMapView *)mv didUpdateUserLocation:(MKUserLocation *)u 方法。

改为使用locationmanager didUpdateToLocation

didUpdateUserLocation 被多次调用,没有任何原因。didUpdateToLocation 在任何位置发生变化时被调用。

然后你可以在didUpdateToLocation方法中手动设置mkmapview区域。

【讨论】:

【参考方案2】:

首先,我不知道这会对事情产生多大影响,但是您是否在 viewDidLoad(或您正在实施 locationManager 的任何地方)中设置您的位置管理器准确性和距离过滤器:

[locationManager setDesiredAccuracy:kCLLocationAccuracyBest];
[locationManager setDistanceFilter:kCLDistanceFilterNone];

其次,检查您源代码中的这两个函数(忽略我在此处列出的实际函数的内容,这只是为了说明和显示用法),如果可能,请提供您的代码这些功能,以便我们更好地协助:

- (void)mapViewDidFinishLoadingMap:(MKMapView *)mapView

    [activityIndicator stopAnimating];


- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation

    NSDate* eventDate = newLocation.timestamp;
    NSTimeInterval howRecent = [eventDate timeIntervalSinceNow];
    if (abs(howRecent) < 15.0)
    
        NSLog(@"New Latitude %+.6f, Longitude %+.6f", newLocation.coordinate.latitude, newLocation.coordinate.longitude);
    

【讨论】:

【参考方案3】:

我在 MKMapViewDelegate 方法中使用 dispatch_once 在开始时只缩放一次。这是代码。

- (void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation      
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^
        CLLocationCoordinate2D newCoordinate = CLLocationCoordinate2DMake(mapView.userLocation.coordinate.latitude, mapView.userLocation.coordinate.longitude);

        MKCoordinateRegion region = MKCoordinateRegionMakeWithDistance(newCoordinate, 500, 500);
        [mapView setRegion:region animated:YES];
    );

【讨论】:

以上是关于防止 MKMapView 不断地重新缩放和重新居中到用户位置的主要内容,如果未能解决你的问题,请参考以下文章

在 UIImageView 内的 UIImage 上缩放和居中

Plotly React 在重新渲染之间保持缩放和旋转

在 MKMapView 中释放缓存

MKMapView 重置回世界视图:重新烘焙

重新进入视图时 iPod 上的 MKMapView 崩溃

我可以重新定位已经放置在 MKMapView 上的 MKAnnotationView 吗?