1

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..

Stpn
  • 6,202
  • 7
  • 47
  • 94
  • Before I answer, do I gather that your intent is to not drag around the annotation view, itself, but rather temporarily replace it with a cross hair or something like that? Usually dragging is incredibly simple, but if you're trying to do something custom, I'm just trying to figure out what you're trying to do. – Rob Feb 26 '13 at 03:50
  • But the short answer is that if you don't like the standard animation of dragging the animation view, you have to subclass `MKAnnotationView` and override `setDragState:animated:` as outlined in the [Marking Your Annotation View as Draggable](http://developer.apple.com/library/ios/documentation/UserExperience/Conceptual/LocationAwarenessPG/AnnotatingMaps/AnnotatingMaps.html#//apple_ref/doc/uid/TP40009497-CH6-SW22) section of Location Awareness Programming Guide._ See example here http://stackoverflow.com/questions/3677166/subclassing-mkannotationview-and-overriding-setdragstate – Rob Feb 26 '13 at 03:54
  • @Stpn: checkout answer from link:- http://stackoverflow.com/questions/14017150/implementing-mkpinannotationview-drag-feature/14017531#14017531 ,you will get idea about that by downloading example source code. – Sunil Zalavadiya Feb 26 '13 at 04:27
  • @Rob - I dont want to replace the pin just add a crosshair that shows where the pin will be dropped.. as it is it's hard to tell where the pin will end once it is dragged.. (b/c it is lifted from the ground and user has to extrapolate the final position of the dropped pin).. – Stpn Feb 26 '13 at 21:38
  • By the way, when you play around with this, I think you'll notice that the pin will end up being dropped where to point of the pin is. That's where I ended up placing my crosshair. – Rob Feb 27 '13 at 15:27

1 Answers1

1

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;
}
Rob
  • 415,655
  • 72
  • 787
  • 1,044