Christopher
Christopher

Reputation: 731

unable to add tap gesture to customized calloutView

I have a mapview in my app which needs customized calloutView for every map annotations. Therefore, I have an XIB file for this customized calloutView. Here is my code for the map view controller

- (void)mapView:(MKMapView *)mapView didSelectAnnotationView:(MKAnnotationView *)view {
    CustomCalloutView *calloutView = (CustomCalloutView *)[[[NSBundle mainBundle] loadNibNamed:@"CustomCalloutView" owner:self options:nil] objectAtIndex:0];
    [calloutView.layer setCornerRadius:10];
    CGRect calloutViewFrame = calloutView.frame;
    calloutViewFrame.origin = CGPointMake(-calloutViewFrame.size.width/2 + 15, -calloutViewFrame.size.height);
    calloutView.frame = calloutViewFrame;

    // some other code such as load images for calloutView

    UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleSingleTap)];
    singleTap.numberOfTapsRequired = 1;
    [calloutView addGestureRecognizer:singleTap];
    [view addSubview:calloutView];
}

- (void)handleSingleTap{
    NSLog(@"it works");
}

However, the handleSingleTap: has never been called. Instead, every tap on the calloutView will only simply dismiss the calloutView. I also tried to add a button on the calloutView, but tap on it will also cause the calloutView dismissing, rather than calling the button action.

Can anyone help?

Update:

I've tried to change the code

    [view addSubview:calloutView];

to

    [self.view addSubview:calloutView];

which add the customized calloutView into the main container view rather than the mapView.

Then, it works fine with the tap gesture. Therefore, I think the problem should be caused by the mapView, it seems that mapView passes all the touch event on calloutView to itself. Anyone have ideas regarding this?

Upvotes: 1

Views: 373

Answers (2)

Christopher
Christopher

Reputation: 731

OK. I worked out the solution finally. We need to have a customized class for the MKAnnotationView to solve this. Here is the code in the .m file

- (UIView*)hitTest:(CGPoint)point withEvent:(UIEvent*)event
{
    UIView* hitView = [super hitTest:point withEvent:event];
    if (hitView != nil)
    {
        [self.superview bringSubviewToFront:self];
    }
    return hitView;
}

- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent*)event
{
    CGRect rect = self.bounds;
    BOOL isInside = CGRectContainsPoint(rect, point);
    if(!isInside)
    {
        for (UIView *view in self.subviews)
        {
            isInside = CGRectContainsPoint(view.frame, point);
            if(isInside)
                break;
        }
    }
    return isInside;
}

Hopefully this can be helpful for others.

Upvotes: 1

Nilesh_iOSDev
Nilesh_iOSDev

Reputation: 671

You need to modify your tapgesture implemenation & the method called.Have a look & check whether it work or not.

UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleSingleTap)];
singleTap.numberOfTapsRequired = 1;
[calloutView addGestureRecognizer:singleTap];
[view addSubview:calloutView];


- (void)handleSingleTap:(UIGestureRecognizer *)recognizer {
    NSLog(@"it works");
}

Upvotes: 0

Related Questions