我为用户位置创建了一个自定义MKAnnotationView:
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation
Run Code Online (Sandbox Code Playgroud)
{
if ([annotation isKindOfClass:[MKUserLocation class]]) {
if (navStatus == NavStatusHeadingEnabled) {
if ([annotation isKindOfClass:[MKUserLocation class]]) {
locationView = [[CustomLocationView alloc] initWithAnnotation:annotation reuseIdentifier:@"locationIdentifier"];
return locationView;
}
}
return nil;
}
Run Code Online (Sandbox Code Playgroud)
CustomLocationView.h
- (id)initWithAnnotation:(id <MKAnnotation>)annotation reuseIdentifier:(NSString *)reuseIdentifier
{
self = [super initWithAnnotation:annotation reuseIdentifier:reuseIdentifier];
if (self != nil)
{
self.backgroundColor = [UIColor clearColor];
blueDot = [UIImage imageNamed:@"userLocationDot.png"].CGImage;
CGImageRetain(blueDot);
CGPoint blueDotCenter = CGPointMake((self.frame.size.width - (CGImageGetWidth(blueDot) / 2)) / 2, (self.frame.size.height - (CGImageGetHeight(blueDot) / 2)) / 2);
blueDotLayer = [CALayer layer];
blueDotLayer.frame = CGRectMake(blueDotCenter.x, blueDotCenter.y , CGImageGetWidth(blueDot) / 2, CGImageGetHeight(blueDot) / 2);
blueDotLayer.contents = (id)blueDot;
blueDotLayer.shadowOpacity = 0.4;
blueDotLayer.shadowColor = [UIColor blackColor].CGColor;
blueDotLayer.shadowOffset = CGSizeMake(0.4, 0.3);
blueDotLayer.shadowRadius = 1.0f;
[self.layer insertSublayer:blueDotLayer above:self.layer];
}
return self;
}
- (void)setAnnotation:(id <MKAnnotation>)annotation
{
[super setAnnotation:annotation];
[self setNeedsDisplay];
}
- (void)dealloc {
[blueDotLayer release];
[super dealloc];
}
Run Code Online (Sandbox Code Playgroud)
问题是它只是停留在同一个地方而不像蓝点那样移动.我做错了什么?
谢谢比尔.
我刚刚遇到了这个问题.我不确定这是否是预期的行为,但无论出于何种原因,我们都应该移动我们的自定义MKUserLocation注释视图.
一个天真的解决方案是
- (void) locationController: (LocationController *) locationController
didUpdateToLocation: (CLLocation *) location
{
[[self mapView] setShowsUserLocation:NO];
[[self mapView] setShowsUserLocation:YES];
}
Run Code Online (Sandbox Code Playgroud)
但是这使得当前位置注释在屏幕周围跳跃,我发现这是不合需要的.
更好的是在视图控制器中将自定义注释视图的引用保持为ivar然后执行:
- (void) locationController: (LocationController *) locationController
didUpdateToLocation: (CLLocation *) location
{
CGPoint newCenterPoint = [[self mapView] convertCoordinate:[location coordinate] toPointToView:[[self customAnnotationView] superview]];
newCenterPoint.x += [[self customAnnotationView] centerOffset].x;
newCenterPoint.y += [[self customAnnotationView] centerOffset].y;
[UIView animateWithDuration:0.3f animations:^{
[[self customAnnotationView] setCenter:newCenterPoint];
}];
}
Run Code Online (Sandbox Code Playgroud)
这很好,除非您更改缩放级别时注释保持在相对于地图视图的rect的位置,然后仅在缩放或平移完成后才动画到正确的位置.最好遵循Apple的主导并使当前位置注释消失并在区域更改期间重新出现:
- (void)mapView:(MKMapView *)mapView regionWillChangeAnimated:(BOOL)animated
{
[[self mapView] setShowsUserLocation:NO];
}
- (void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated
{
[[self mapView] setShowsUserLocation:YES];
}
Run Code Online (Sandbox Code Playgroud)
账单,
您需要一个已使用适用的desiredAccuracy 和distanceFilter 进行初始化的CLLocationManager,然后实现适用的委托方法,并将您自己的代码设置为locationManager 实例上的委托。
至少,您应该具有以下方法,位置管理器在确定所需精度中的当前位置后将调用该方法,然后每当满足 distanceFilter 时再次调用该方法。
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation ;
Run Code Online (Sandbox Code Playgroud)
干杯,麦克