A: 

Hey I see nobody has answered you, and I just figured out how to do this. Unfortunately you cannot intercept events and forward them to the mapView so something like

@interface MapOverlay
   MKMapView* map;
@end

@implementation
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
   // Do my stuff
   foo();
   bar();
   // Forward to the map
   [map touchesBegan....];
}
@end

This is what you want to do but it WILL NOT WORK. For some reason you cannot intercept the map's events, nor can you do the reverse and subclass MKMapView and overload it's touch methods. The only way I have found to do this is as follows.

Create your MapOverlay view, set it to have a transparent background and disable touches to it. Overlay this on top of your MKMapView. Then do the following

Subclass UIWindow with a custom class that will forward all touches to your overlay, either handling the logic as "if the overlay is not hidden, then forward", or in the overlay itself keep state. Anyway it looks like this

@implementation CustomWindow

- (void)sendEvent:(UIEvent*)event
{
   [super sendEvent:event];
   // Forward the event to the overlay
}

When you are forwarding the event to the overlay, you first check if the touches are inside of your mapView region, then figure out what type of touches they are, then call the correct touch method on your overlay.

Good luck!

DevDevDev
A: 

I know this answer probably comes too late, but I'll take a stab anyway for the benefit of those (such as myself) who've also come across this problem as well.

The MKMapView class's touch events are all handled by a UIScrollView internally. You can capture the events of this scroll view by making the MKMapView a subview of a custom UIView, and providing your custom touches methods in the custom view.

The trick is to keep track of the UIScrollView used by the MKMapView. To do this, I overrode the "hitTest" method, which returns "self", which I believe means this custom view should handle the touch events.

Also, the hitTest method gets the UIScrollView of the MKMapView. In my custom UIView I called it "echo_to" because the events are then echoed to the UIScrollView to make the map work as it does normally.


- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {

    //  Get the UIView (in this case, a UIScrollView) that
    //  would ordinarily handle the events
    echo_to = [super hitTest:point withEvent:event];

    //  But let it be known we'll handle them instead.
    return self;
}

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {

    NSLog(@"Touches Began");
    //  add your custom annotation behavior here
    [echo_to touchesBegan:touches withEvent:event];
}

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {

    NSLog(@"Touches moved");
    //  add your custom annotation behavior here
    [echo_to touchesMoved:touches withEvent:event];
}

Best of luck.

Tom
A: 

Depending on the sophistication of your geometryView, you may be able to use an annotation view to draw it.

The downside to this approach is that the view won't scale with the map (although you can use the mapView:regionDidChangeanimated: delegate method to redraw after a zoom), but it will pan with the map.

Frank Schmitt
A: 

The hitTest trick works great as long as you don't need users to be able to tap on annotations, or pinch-and-zoom the map. Neither of these are able to be forwarded.

juggleware