简体   繁体   中英

iOS MapKit custom callout on the side of the pin

I want to implement a custom callout view for iOS that shows on the right side of the pin that gets tapped. The way I ended up doing is sort of like this tutorial.
Basically I add a subview to the annotation view in the mapView:didSelectAnnotationView: delegate callback (the second argument is the annotation view). It shows up just how I'd like BUT it can't receive touch events. I figured out that it's ( probably ) because the UIView I add is out of the annotation view's frame, if I tap the edge what's still in the frame, it gets recognized, but nowhere else. I haven't yet found any other way to do such thing than this and I don't know how to make the touch work everywhere in the UIView.
I tried making the frame of the annotation view bigger but it also makes the pin (image) bigger and it isn't a way to go.

Any ideas?

Don't add a subview to the annotation, instead subclass MKAnnotationView and implement the required methods. If you want total control over the drawing just override -drawRect: . Remember that MKAnnotationView is a special class that is a little bit like UITableViewCell in that it has some special handling for being queued and dequed and you should use it directly. Here's an example to get your started.

- (id)initWithAnnotation:(id<MKAnnotation>)annotation reuseIdentifier:(NSString *)reuseIdentifier
{
    self = [super initWithAnnotation:annotation reuseIdentifier:reuseIdentifier];
    if (self) {
        [self commonInit];
    }
    return self;
}

- (id)initWithCoder:(NSCoder *)aDecoder
{
    self = [super initWithCoder:aDecoder];
    if (self) {
        [self commonInit];
    }
    return self;
}

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        [self commonInit];
    }
    return self;

}

- (id)init
{
    self = [super init];
    if (self) {
        [self commonInit];
    }
    return self;
}

- (void)commonInit
{
    self.frame = CGRectMake(0, 0, 40, 40);
    self.backgroundColor = [UIColor clearColor];
    self.canShowCallout = YES;
}

- (void)drawRect:(CGRect)rect
{
    //// Oval Drawing
    CGRect imageBox = CGRectMake(5, 5, 25, 25);
    UIBezierPath* ovalPath = [UIBezierPath bezierPathWithOvalInRect:imageBox];
    [[UIColor clouds] setFill];
    [ovalPath fill];
    [[UIColor clouds] setStroke];
    ovalPath.lineWidth = 6;
    [ovalPath stroke];

    CGFloat radius = imageBox.size.width / 2;
    UIImage *img = [UIView rasterizedStatusImageForCheckpoint:self.checkpoint withSize:imageBox.size];
    img = [img makeRoundedImage:img radius:radius];
    [img drawInRect:imageBox];
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM