我为用户位置创建了一个自定义MKAnnotationView:
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation
{
if ([annotation isKindOfClass:[MKUserLocation class]]) {
if (navStatus == NavStatusHeadingEnabled) {
if ([annotation isKindOfClass:[MKUserLocation class]]) {
locationView = [[CustomLocationView alloc] initWithAnnotation:annotation reuseIdentifier:@"locationIdentifier"];
return locationView;
}
}
return nil;
}
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];
}
问题是它只是停留在同一个地方而不像蓝点那样移动。 我做错了什么?
由于 比尔。
答案 0 :(得分:5)
我刚才遇到了这个问题。我不确定这是否是预期的行为,但无论出于何种原因,我们都应该移动我们的自定义MKUserLocation注释视图。
一个天真的解决方案
- (void) locationController: (LocationController *) locationController
didUpdateToLocation: (CLLocation *) location
{
[[self mapView] setShowsUserLocation:NO];
[[self mapView] setShowsUserLocation:YES];
}
但是这使得当前位置注释在屏幕上跳跃,我发现这是不合需要的。
最好是在视图控制器中将自定义注释视图的引用保持为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];
}];
}
这很好,除非您更改缩放级别时注释保持相对于地图视图的rect的位置,然后仅在缩放或平移完成后才动画到正确的位置。最好遵循Apple的主导并使当前位置注释消失并在区域更改期间重新出现:
- (void)mapView:(MKMapView *)mapView regionWillChangeAnimated:(BOOL)animated
{
[[self mapView] setShowsUserLocation:NO];
}
- (void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated
{
[[self mapView] setShowsUserLocation:YES];
}
答案 1 :(得分:0)
比尔,
您需要一个已使用适用的desiredAccuracy和distanceFilter初始化的CLLocationManager,然后实现适用的委托方法,并将您自己的代码设置为locationManager实例上的委托。
至少应该使用以下方法,一旦位置管理器确定了当前所在位置的位置,然后在满足distanceFilter时再次调用该方法。
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation ;
干杯, 麦克
答案 2 :(得分:0)
我刚刚找到了这个问题的答案。我的代码在Monotouch中,但在ObjC中重新执行相同的操作应该很容易。
要在默认MKUserLocation
上显示自定义图像,我们需要在原始图像之上添加子视图。要执行此操作,请覆盖DidAddAnnotationViews
代理
MKMapView
void DidAddAnnotationViews (object sender, MKMapViewAnnotationEventArgs e)
{
MKAnnotationView v = mapView.ViewForAnnotation(mapView.UserLocation);
if(v != null)
{
if(v.Subviews.Count() == 0)
{
UIImageView iv = new UIImageView(new RectangleF(0,0, 22, 22));
iv.Image = UIImage.FromFile("res/pins/Yhere.png");
v.AddSubview(iv);
v.BringSubviewToFront(iv);
}
}
}
这使自定义图像在蓝点上移动。更重要的是,用户跟踪和位置更新功能完美无缺,您仍然可以看到指示位置准确性的蓝色圆圈。
有乐趣自定义MKUserLocation!
答案 3 :(得分:0)
以下是Apple Developer Technical Support
的答案我刚刚与MapKit工程师交谈,他们确认这是iOS中的一个错误。 我的测试应用程序遇到了同样的问题。
我不知道这是否已在iOS 6中修复,答案是针对iOS 5。