Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Callout doesn't work if opened, after tapping an other Pin. #64

Closed
MarcoSpeziali opened this issue Aug 26, 2014 · 12 comments
Closed

Callout doesn't work if opened, after tapping an other Pin. #64

MarcoSpeziali opened this issue Aug 26, 2014 · 12 comments

Comments

@MarcoSpeziali
Copy link

If the callout view is opened and I tap on an other Pin the callout just disappears
I uploaded a video: http://videobam.com/mlSeK

@nfarina
Copy link
Owner

nfarina commented Aug 26, 2014

Hi, are you using MKMapView or a custom view to host your callout?

@MarcoSpeziali
Copy link
Author

No I'm using a custom one, implemented exactly as you did in the example you gave us...

@MarcoSpeziali
Copy link
Author

If you want to see my code here it is:

- (void)mapView:(MKMapView *)mapView didSelectAnnotationView:(MKAnnotationView *)annotationView {
    // apply the MKAnnotationView's basic properties
    self.calloutView.title = annotationView.annotation.title;
    self.calloutView.subtitle = annotationView.annotation.subtitle;

    // Apply the MKAnnotationView's desired calloutOffset (from the top-middle of the view)
    self.calloutView.calloutOffset = annotationView.calloutOffset;

    // iOS 7 only: Apply our view controller's edge insets to the allowable area in which the callout can be displayed.
    self.calloutView.constrainedInsets = UIEdgeInsetsMake(self.topLayoutGuide.length, 0, self.bottomLayoutGuide.length, 0);

    // This does all the magic.
    [self.calloutView presentCalloutFromRect:annotationView.bounds inView:annotationView constrainedToView:self.view animated:YES];
}

- (void)mapView:(MKMapView *)mapView didDeselectAnnotationView:(MKAnnotationView *)view {
    [self.calloutView dismissCalloutAnimated:YES];
}

#pragma mark - SMCalloutView Delegate

- (NSTimeInterval)calloutView:(SMCalloutView *)calloutView delayForRepositionWithSize:(CGSize)offset {

    // When the callout is being asked to present in a way where it or its target will be partially offscreen, it asks us
    // if we'd like to reposition our surface first so the callout is completely visible. Here we scroll the map into view,
    // but it takes some math because we have to deal in lon/lat instead of the given offset in pixels.

    CLLocationCoordinate2D coordinate = self.mapView.centerCoordinate;

    // where's the center coordinate in terms of our view?
    CGPoint center = [self.mapView convertCoordinate:coordinate toPointToView:self.view];

    // move it by the requested offset
    center.x -= offset.width;
    center.y -= offset.height;

    // and translate it back into map coordinates
    coordinate = [self.mapView convertPoint:center toCoordinateFromView:self.view];

    // move the map!
    [self.mapView setCenterCoordinate:coordinate animated:YES];

    // tell the callout to wait for a while while we scroll (we assume the scroll delay for MKMapView matches UIScrollView)
    return kSMCalloutViewRepositionDelayForUIScrollView;
}

This is how I configure the calloutView:

self.calloutView = [SMCalloutView platformCalloutView];
    self.calloutView.delegate = self;
    [self.calloutView setUserInteractionEnabled:YES];

    /* Left View */

    UIImageView *carView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"car"]];

    // wrap it in a blue background on iOS 7+
    UIButton *blueView = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 44, 44 + 30)];
    blueView.backgroundColor = [UIColor colorWithRed:94.0f/255.0f green:94.0f/255.0f blue:94.0f/255.0f alpha:1];
    [blueView addTarget:self action:@selector(carTapped:) forControlEvents:UIControlEventTouchUpInside];
    [blueView setUserInteractionEnabled:YES];

    UIGestureRecognizer *carRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self
                                                                                 action:@selector(carTapped:)];
    [blueView addGestureRecognizer:carRecognizer];

    carView.frame = CGRectMake(11, 14, carView.image.size.width, carView.image.size.height);
    [blueView addSubview:carView];

    self.calloutView.leftAccessoryView = blueView;

    /* Right View */

    UIImageView *rightView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"UITableNext"]];
    [rightView setUserInteractionEnabled:YES];

    UIGestureRecognizer *arrowRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self
                                                                                   action:@selector(arrowTapped:)];
    [rightView addGestureRecognizer:arrowRecognizer];


    self.calloutView.rightAccessoryView = rightView;
    self.calloutView.rightAccessoryView.alpha = 0.2;

    self.mapView.calloutView = self.calloutView;

And my MapView:

// this tells the compiler that MKMapView actually implements this method
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch;

@end

@implementation MSMapView

// override UIGestureRecognizer's delegate method so we can prevent MKMapView's recognizer from firing
// when we interact with UIControl subclasses inside our callout view.
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch {
    if ([touch.view isKindOfClass:[UIControl class]])
        return NO;
    else
        return [super gestureRecognizer:gestureRecognizer shouldReceiveTouch:touch];
}

// Allow touches to be sent to our calloutview.
// See this for some discussion of why we need to override this: https://github.com/nfarina/calloutview/pull/9
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {

    UIView *calloutMaybe = [self.calloutView hitTest:[self.calloutView convertPoint:point fromView:self] withEvent:event];
    if (calloutMaybe) return calloutMaybe;

    return [super hitTest:point withEvent:event];
}

@nfarina
Copy link
Owner

nfarina commented Aug 26, 2014

I think I've fixed the issue - can you try again with the latest code?

@MarcoSpeziali
Copy link
Author

May you update also the podspec? Because running pod update doesn't updated SMCalloutView

Actually I don't know if you have to update the podspec or something else...

@nfarina
Copy link
Owner

nfarina commented Aug 26, 2014

I'd like to verify that the issue is fixed before updating the podspec. Can you download the latest SMCalloutView.m from Github here and drop that in?

@MarcoSpeziali
Copy link
Author

Yes now it works perfectly! 👍
You are awesome!

@MarcoSpeziali
Copy link
Author

If you have a minute may you explain this to me?
CGFloat $x

@nfarina
Copy link
Owner

nfarina commented Aug 26, 2014

Excellent! I'll update the podspec when I can.

The $x style properties are extension methods used internally by SMCalloutView to help make the code cleaner. Internally, they're simply updating the frame property, but with a nicer syntax. You can read more about it in the "UIView Frame Helpers" section in my original post: http://nfarina.com/post/29883229869/callout-view

@nfarina
Copy link
Owner

nfarina commented Aug 26, 2014

Podspec is updated.

@MarcoSpeziali
Copy link
Author

Ok, thank you! Awesome library by the way! :)

Il giorno 26/ago/2014, alle ore 18:53, Nick Farina [email protected] ha scritto:

Podspec is updated.


Reply to this email directly or view it on GitHub.

This message has been scanned for viruses and dangerous content by
Stop-Spam System, and is believed to be clean.

@incanus
Copy link
Contributor

incanus commented Aug 26, 2014

BTW @Marsh321 you should check this out in the CocoaPods docs:

http://guides.cocoapods.org/using/the-podfile.html

Look at Using the files from a folder local to the machine. and From a podspec in the root of a library repo. since this project has a SMCalloutView.podspec right in it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants