当userLocation的视图是自定义时,不会调用didUpdateUserLocation

Pat*_*ini 7 geolocation mapkit mkmapview ios mkmapviewdelegate

我有一个MKMapView应该使用自定义视图(而不是蓝点)跟踪用户的位置.为了将此视图替换为蓝点,我将其返回:

- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation
{
    if (annotation == [mapView userLocation])
    {
        return userLocationView;
    }
}
Run Code Online (Sandbox Code Playgroud)

为了初始化跟踪,我打电话

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

正如预期的那样,-mapView:didUpdateUserLocation:当应用程序加载时会调用一次.不幸的是,除非我-mapView:viewForAnnotation:改为具有以下实现,否则它永远不会被再次调用:

- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation
{
    if (annotation == [mapView userLocation])
    {
        return nil;
    }
}
Run Code Online (Sandbox Code Playgroud)

通过这些更改,地图会加载蓝点作为用户位置的指示符,并且-mapView:didUpdateUserLocation:会像预期的那样频繁调用.

是否有某种互斥性来跟踪用户的位置并拥有自定义用户位置视图?我怎么能让两者都发生?

资源

该项目证明了这个问题.https://dl.dropbox.com/u/2338382/MapKitFuckery.zip

窃听器

这很可能是一个错误,我已将其作为雷达提交.在此期间,接受的答案应该证明是充分的.然而,值得注意的是,我必须完全放弃,[mapView userLocation]并且[mapView showsUserLocation]仅仅支持自定义注释和CLLocationManager.

nev*_*ing 11

而不是依赖于地图视图的位置更新,启动a CLLocationManager,设置delegate并等待-locationManager:didUpdateToLocation:fromLocation:(在iOS 5及更低版本中)或-locationManager:didUpdateLocations:(iOS 6).与使用地图视图的委托方法相比,您将获得更可靠,更丰富的信息.你可能知道这样做的方法,但它是:

#import <CoreLocation/CoreLocation.h>

- (void)viewWillAppear:(BOOL)animated
{
    self.locationManager = [[CLLocationManager alloc] init];
    self.locationManager.delegate = self;
    [self.locationManager setDesiredAccuracy:kCLLocationAccuracyBest];
    [self.locationManager startUpdatingLocation];
}

// Deprecated in iOS 6
- (void)locationManager:(CLLocationManager *)manager
    didUpdateToLocation:(CLLocation *)newLocation
           fromLocation:(CLLocation *)oldLocation
{

    // Check the age of the newLocation isn't too long ago using newLocation.timestamp

    // Set the map dot using newLocation.coordinate

    // Set an MKCircle to represent accuracy using newLocation.horizontalAccuracy
}
Run Code Online (Sandbox Code Playgroud)

我看了一下代表调用进入mapView的委托,并返回除了nil停止调用之外的任何内容-mapView:didUpdateUserLocation:,就像你说的那样.以下是他们到达顺序的电话:

 - (void)mapViewWillStartLocatingUser:(MKMapView *)mapView
 - (void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation
 - (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id < MKAnnotation >)annotation
 - (void)mapViewWillStartLoadingMap:(MKMapView *)mapView
 - (void)mapView:(MKMapView *)mapView didFailToLocateUserWithError:(NSError *)error
Run Code Online (Sandbox Code Playgroud)

可能是MKUserLocation对象,而不是MKMapView负责通过更新调用调用委托的对象.如果您检查的地位showsUserLocationmapView.userLocation,他们都看起来不错:

NSLog(@"%d %@", mapView.showsUserLocation, mapView.userLocation);
Run Code Online (Sandbox Code Playgroud)

返回1和一个非零对象(1 <MKUserLocation: 0x1e02e580>).也许mapView查询的userLocation对象是获取当前位置,然后将其发送给委托.如果该对象已经消失,它将无法工作.

这有点奇怪,但就像我说的那样,你会从更新中获得更好CLLocationManager的更新.