Stpn
Stpn

Reputation: 6394

Show the location of a dragged MKAnnotationPin

I am trying to add some kind of indicator for the location of the dragged MKAnnotationPin..

So far I came up with the following non-working solution:

- (void) showDragLoc{


UIView *cross = [[UIView alloc] initWithFrame:CGRectMake(dragPin.center.x, dragPin.center.y, 10, 10)];
[self.mapView addSubview:cross];
while(dragPin.dragState  == MKAnnotationViewDragStateDragging){

    [UIView beginAnimations:nil context:NULL]; // animate the following:
    cross.frame = CGRectMake(dragPin.center.x, dragPin.center.y, 10, 10); // move to new location
    [UIView setAnimationDuration:0.3];
    [UIView commitAnimations];
}
}

ere dragPin is the MKAnnotationView that is declared in the header.. This function is called when the dragState of the pin goes to MKAnnotationViewDragStateDragging (from the delegate method)..

My goal is to add some kind of indicator of where the dragged pin currently is..

Upvotes: 1

Views: 255

Answers (1)

Rob
Rob

Reputation: 437492

If you want to add a crosshair to the standard MKPinAnnotationView, you should subclass it and then add your crosshair in your implementation of setDragState:animated:.

So, to subclass, create a new class, e.g., PinWithCrosshairAnnotationView. The .h public interface doesn't need much:

@interface PinWithCrosshairAnnotationView : MKPinAnnotationView

@end

The .m implementation just implements a setDragState:animated: that adds your crosshair and then calls the super implementation to get the pin pulling and dropping features. I'm also animating that, if the animated flag is on, but you don't have to. Your frame coordinates will undoubtedly be different from mine, but I gather from your code sample above that you've already figured out the right values for your crosshair image:

#import "PinWithCrosshairAnnotationView.h"

@interface PinWithCrosshairAnnotationView ()
@property (nonatomic, weak) UIImageView *crosshairImageView;
@end

@implementation PinWithCrosshairAnnotationView

- (void)setDragState:(MKAnnotationViewDragState)newDragState animated:(BOOL)animated
{
    if (newDragState == MKAnnotationViewDragStateStarting)
    {
        // create the crosshair imageview and add it as a subview

        UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(-1.5, 30, 17.5, 17.5)];
        imageView.image = [UIImage imageNamed:@"Crosshairs.png"];
        [self addSubview:imageView];

        // if the animated flag is on, we'll fade it to visible state

        if (animated)
        {
            imageView.alpha = 0.0;
            [UIView animateWithDuration:0.2
                             animations:^{
                                 imageView.alpha = 1.0;
                             }];
        }

        // save a reference to that imageview in a class property

        self.crosshairImageView = imageView;
    }
    else if (newDragState == MKAnnotationViewDragStateEnding || newDragState == MKAnnotationViewDragStateCanceling)
    {
        if (animated)
        {
            // if we're animating, let's quickly fade it to invisible
            // and in the completion block, we'll remove it

            [UIView animateWithDuration:0.2
                             animations:^{
                                 self.crosshairImageView.alpha = 0.0;
                             }
                             completion:^(BOOL finished) {
                                 [self.crosshairImageView removeFromSuperview];
                                 self.crosshairImageView = nil;
                             }];
        }
        else
        {
            // if we're not animating, just remove it

            [self.crosshairImageView removeFromSuperview];
            self.crosshairImageView = nil;
        }
    }

    // remember to call super so we get all the other wonderful superclass behavior

    [super setDragState:newDragState animated:animated];
}
@end

And obviously, you'd then customize the viewForAnnotation in your MKMapView delegate accordingly. This is a minimalist version, but you'd obviously adjust yours depending upon your needs (callouts, title, subtitle, etc.):

- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation
{
    if ([annotation isKindOfClass:[MKUserLocation class]])
        return nil;

    MKAnnotationView *view = [[PinWithCrosshairAnnotationView alloc] initWithAnnotation:annotation
                                                                        reuseIdentifier:@"pinwithcrosshairannotation"];
    view.draggable = YES;
    view.canShowCallout = NO;

    return view;
}

Upvotes: 1

Related Questions