MKUserLocation Custom View not moving!

五迷三道 提交于 2019-12-21 04:25:20

问题


I have created a custom MKAnnotationView for User Location:

- (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];
}

The problem is it just stays on the same place and not moving like the blue dot. What I am doing wrong?

Thanks Bill.


回答1:


I ran into this problem just now as well. I'm not sure if this is expected behavior or not, but for whatever reason it is up to us to move our custom MKUserLocation annotation views.

A naive solution is

- (void) locationController: (LocationController *) locationController
        didUpdateToLocation: (CLLocation *) location
{
    [[self mapView] setShowsUserLocation:NO];

    [[self mapView] setShowsUserLocation:YES];
}

But this makes the current location annotation jump around the screen which I found undesirable.

Better yet is to keep a reference to the custom annotation view as an ivar in your view controller and then do:

- (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];
    }];

}

This is good except when you change the zoom level the annotation stays where it was relative to the map view's rect and then animates to the correct location only after the zoom or pan is complete. Best to follow Apple's lead and make the current location annotation disappear and reappear during region changes:

- (void)mapView:(MKMapView *)mapView regionWillChangeAnimated:(BOOL)animated
{
    [[self mapView] setShowsUserLocation:NO];
}

- (void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated
{
    [[self mapView] setShowsUserLocation:YES];
}



回答2:


Bill,

You need a CLLocationManager that has been initialized with an applicable desiredAccuracy and distanceFilter and then implement the applicable delegate methods, and set your own code as the delegate on the locationManager instance.

At a minimum you should have the following method which the Location Manager will call once it has determined the current location with in the desiredAccuracy and then again whenever the distanceFilter has been met.

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

Cheers, Mack




回答3:


I just found an answer for this problem. My code is in Monotouch, but it should be easy to re-do the same in ObjC. to show customized image over default MKUserLocation we need to add a subview on top of the original one. to do this, override DidAddAnnotationViews in MKMapView delegate

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);
                }
            }
}

This gives custom image moving on top of blue dot. more over, user tracking and location updates features works perfectly and you still can see blue circles that indicate location accuracy.

Have fun customizing MKUserLocation!




回答4:


Here is the answer from Apple Developer Technical Support

I just finished talking to the MapKit engineers and they confirmed that this is a bug in iOS. My test app is experiencing the same problem.

I don't know if this was fixed in iOS 6, the answer is for the iOS 5.



来源:https://stackoverflow.com/questions/5769363/mkuserlocation-custom-view-not-moving

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!