How to customize the callout bubble for MKAnnotationView?
I'm currently working with the mapkit and am stuck.
I have a custom annotation view I am using, and I want to use the image property to display the point on the map with my own icon. I have this working fine. But what I would also like to do is to override the default callout view (the bubble that shows up with the title/subtitle when the annotation icon is touched). I want to be able to control the callout itself: the mapkit only provides access to the left and right ancillary callout views, but no way to provide a custom view for the callout bubble, or to give it zero size, or anything else.
My idea was to override selectAnnotation/deselectAnnotation in my MKMapViewDelegate
, and then draw my own custom view by making a call to my custom annotation view. This works, but only when canShowCallout
is set to YES
in my custom annotation view class. These methods are NOT called if I have this set to NO
(which is what I want, so that the default callout bubble is not drawn). So I have no way of knowing if the user touched on my point on the map (selected it) or touched a point that is not part of my annotation views (delected it) without having the default callout bubble view show up.
I tried going down a different path and just handling all touch events myself in the map, and I can't seem to get this working. I read other posts related to catching touch events in the map view, but they aren't exactly what I want. Is there a way to dig into the map view to remove the callout bubble before drawing? I'm at a loss.
Any suggestions? Am I missing something obvious?
There is an even easier solution.
Create a custom UIView
(for your callout).
Then create a subclass of MKAnnotationView
and override setSelected
as follows:
- (void)setSelected:(BOOL)selected animated:(BOOL)animated
{
[super setSelected:selected animated:animated];
if(selected)
{
//Add your custom view to self...
}
else
{
//Remove your custom view...
}
}
Boom, job done.
detailCalloutAccessoryView
In the olden days this was a pain, but Apple has solved it, just check the docs on MKAnnotationView
view = MKPinAnnotationView(annotation: annotation, reuseIdentifier: identifier)
view.canShowCallout = true
view.detailCalloutAccessoryView = UIImageView(image: UIImage(named: "zebra"))
Really, that's it. Takes any UIView.
Continuing on from @TappCandy's brilliantly simple answer, if you want to animate your bubble in the same way as the default one, I've produced this animation method:
- (void)animateIn
{
float myBubbleWidth = 247;
float myBubbleHeight = 59;
calloutView.frame = CGRectMake(-myBubbleWidth*0.005+8, -myBubbleHeight*0.01-2, myBubbleWidth*0.01, myBubbleHeight*0.01);
[self addSubview:calloutView];
[UIView animateWithDuration:0.12 delay:0.0 options:UIViewAnimationOptionCurveEaseOut animations:^(void) {
calloutView.frame = CGRectMake(-myBubbleWidth*0.55+8, -myBubbleHeight*1.1-2, myBubbleWidth*1.1, myBubbleHeight*1.1);
} completion:^(BOOL finished) {
[UIView animateWithDuration:0.1 animations:^(void) {
calloutView.frame = CGRectMake(-myBubbleWidth*0.475+8, -myBubbleHeight*0.95-2, myBubbleWidth*0.95, myBubbleHeight*0.95);
} completion:^(BOOL finished) {
[UIView animateWithDuration:0.075 animations:^(void) {
calloutView.frame = CGRectMake(-round(myBubbleWidth/2-8), -myBubbleHeight-2, myBubbleWidth, myBubbleHeight);
}];
}];
}];
}
It looks fairly complicated, but as long as the point of your callout bubble is designed to be centre-bottom, you should just be able to replace myBubbleWidth
and myBubbleHeight
with your own size for it to work. And remember to make sure your subviews have their autoResizeMask
property set to 63 (ie "all") so that they scale correctly in the animation.
:-Joe
链接地址: http://www.djcxy.com/p/67268.html