I'm developing app, where user is localized by gps and then he is asked, whether he is located in specific place. To confirm this, callout bubble is presented to him straight away, asking him, if he is at specific place.
As there is alot of similar questions, I was able to do custom callout bubble:
My problem: button is not "clickable"
My guess: because this custom callout is higher than standard callout bubble, I had to place it in negative "frame", therefore button cannot be clicked. Here is my didSelectAnnotationView
method
- (void)mapView:(MKMapView *)mapView didSelectAnnotationView:(MKAnnotationView *)view {
if(![view.annotation isKindOfClass:[MKUserLocation class]]) {
CalloutView *calloutView = (CalloutView *)[[[NSBundle mainBundle] loadNibNamed:@"callOutView" owner:self options:nil] objectAtIndex:0];
CGRect calloutViewFrame = calloutView.frame;
calloutViewFrame.origin = CGPointMake(-calloutViewFrame.size.width/2 + 15, -calloutViewFrame.size.height);
calloutView.frame = calloutViewFrame;
[calloutView.calloutLabel setText:[(MyLocation*)[view annotation] title]];
[calloutView.btnYes addTarget:self
action:@selector(checkin)
forControlEvents:UIControlEventTouchUpInside];
calloutView.userInteractionEnabled = YES;
view.userInteractionEnabled = YES;
[view addSubview:calloutView];
}
}
CalloutView is just simple class with 2 properties(label that shows name of place and button) and with xib.
I have been doing this custom callout bubble for a few days. I tried using "asynchrony solutions" solution but I was unable to add any other kind of button then disclosure button.
My next attempt, was to find something that was easier than asynchrony solutions and modify it to my use. Thats how I found tochi's custom callout.
Based on his work, I was able to customize his bubble and change info button for my custom button. My problem however remained the same. In order to place my custom callout view on top of the pin, I had to give it negative frame, so my button was "clickable" only in bottom 5 pixels. It seems, that I have to maybe dig deeper into ios default callout bubble, subclass it and change frame of callout in there. But I'm really hopeless now.
If you guys could show me the right way, or give me advice, I'll be glad.
Best Answer
There are several approaches to customizing callouts:
The easiest approach is to use the existing right and left callout accessories, and put your button in one of those. For example:
That yields:
If you really don't like the button on the right, where accessories generally go, you can turn off that accessory, and iOS 9 offers the opportunity to specify the
detailCalloutAccessoryView
, which replaces the callout's subtitle with whatever view you want:This yields:
If you really want to develop a custom callout yourself, the Location and Maps Programming Guide outlines the steps involved:
While it's in Swift, https://github.com/robertmryan/CustomMapViewAnnotationCalloutSwift illustrates an example of how you can do this complete customization of the callout (e.g. change shape of callout bubble, change background color, etc.).
That previous point outlines a pretty complicated scenarios (i.e. you have to write your own code to detecting taps outside the view in order to dismiss the it). If you're supporting iOS 9, you might just use a popover view controller, e.g.: