- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation { if (annotation == [mapView userLocation]) { return userLocationView; } }
为了初始化跟踪,我打电话
[mapView setShowsUserLocation: YES]; [mapView setUserTrackingMode: MKUserTrackingModeFollow animated: NO]; [mapView setDelegate: self];
正如所料,-mapView:didUpdateUserLocation:在应用加载时被调用一次.不幸的是,它永远不会被再次调用,除非我更改-mapView:viewForAnnotation:具有以下实现:
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation { if (annotation == [mapView userLocation]) { return nil; } }
通过这些更改,地图会加载蓝点作为用户位置的指示符,并且-mapView:didUpdateUserLocation:会被频繁调用,如预期的那样.
是否存在某种互斥性,用于跟踪用户的位置并拥有自定义用户位置视图?我怎么能让两者都发生?
资源
该项目演示了这个问题. https://dl.dropbox.com/u/2338382/MapKitFuckery.zip
窃听器
这很可能是一个错误,我已将其作为雷达提交.在此期间,接受的答案应该证明是充分的.然而,值得注意的是我不得不完全放弃[mapView userLocation]和[mapView showsUserLocation],而只是简单地使用自定义注释和CLLocationManager.
解决方法
#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 }
我看了一下进入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
据推测,MKUserLocation对象,而不是MKMapView是负责通过更新调用调用委托的对象.如果你检查showsUserLocation和mapView.userLocation的状态,它们看起来都很好:
NSLog(@"%d %@",mapView.showsUserLocation,mapView.userLocation);
返回1和非零对象(1< MKUserLocation:0x1e02e580>).也许mapView查询其userLocation对象以获取当前位置,然后将其发送给委托.如果该对象已经消失,它将无法工作.
这有点奇怪,但就像我说的,你会从CLLocationManager的更新中获得更好的更新.