Custom MKAnnotation callout bubble with button

前端 未结 3 1926
醉话见心
醉话见心 2020-11-27 12:52

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 straig

3条回答
  •  执笔经年
    2020-11-27 13:15

    I wound up taking a different approach. I tried the others but they seemed bloated and I didn't want to add more classes or rely on the MKMapViewDelegate to handle the interaction.

    I instead override setSelected:animated of my MKAnnotationView subclass. The trick is to expand the bounds of the annotationView after it it selected to fully encompass the call out view, and then return them back to normal after it is deselected. This will allow your custom call outs to accept touches and interactions outside the original bounds of the MKAnnotationView.

    Here is a trimmed down code sample to get anyone started:

    #define kAnnotationCalloutBoxTag    787801
    #define kAnnotationCalloutArrowTag  787802
    #define kAnnotationTempImageViewTag 787803
    
    -(void)setSelected:(BOOL)selected animated:(BOOL)animated
    {
        if (selected == self.selected)
        {
            NSLog(@"annotation already selected, abort!");
            return;
        }
        if (selected)
        {
            self.image = nil; //hide default image otherwise it takes the shape of the entire bounds
    
            UIView* calloutBox = [self newCustomCallout];
            float imgW = [self unselectedSize].width;
            float imgH = [self unselectedSize].height;
            float arrowW = 20;
            float arrowH = 12;
    
            //Annotation frames wrap a center coordinate, in this instance we want the call out box to fall under the
            //central coordinate, so we need to adjust the height to be double what the callout box height would be
            //making the height *2, this is to make sure the callout view is inside of it.
            self.bounds = CGRectMake(0, 0, calloutBox.frame.size.width, calloutBox.frame.size.height*2 + arrowH*2 + imgH);
            CGPoint center = CGPointMake(self.bounds.size.width/2, self.bounds.size.height/2);
    
            UIView* imgView = [[UIImageView alloc] initWithImage:icon];
            [imgView setFrame:CGRectMake(center.x - imgW/2, center.y-imgH/2, imgW, imgH)];
            imgView.tag = kAnnotationTempImageViewTag;
            [self addSubview:imgView];
    
            UIView* triangle = [self newTriangleViewWithFrame:CGRectMake(center.x-arrowW/2, center.y+imgH/2, arrowW, arrowH)];
            triangle.tag = kAnnotationCalloutArrowTag;
            [self addSubview:triangle];
    
            [calloutBox setFrame:CGRectMake(0, center.y+imgH/2+arrowH, calloutBox.width, calloutBox.height)];
            calloutBox.tag = kAnnotationCalloutBoxTag;
            [self addSubview:calloutBox];
        }
        else
        {
            //return things back to normal
            UIView* v = [self viewWithTag:kAnnotationCalloutBoxTag];
            [v removeFromSuperview];
            v = [self viewWithTag:kAnnotationCalloutArrowTag];
            [v removeFromSuperview];
            v = [self viewWithTag:kAnnotationTempImageViewTag];
            [v removeFromSuperview];
    
            self.image = icon;
            self.bounds = CGRectMake(0, 0, [self unselectedSize].width, [self unselectedSize].height);
        }
        [super setSelected:selected animated:animated];
    }
    
    -(CGSize)unselectedSize
    {
        return CGSizeMake(20,20);
    }
    
    -(UIView*)newCustomCallout
    {
        //create your own custom call out view
        UIView* v = [[UIView alloc] initWithFrame:CGRectMake(0,0,250,250)];
        v.backgroundColor = [UIColor greenColor];
        return v;
    }
    
    -(UIView*)newTriangleWithFrame:(CGRect)frame
    {
        //create your own triangle
        UIImageView* v = [[UIImageView alloc] initWithFrame:frame];
        [v setImage:[UIImage imageNamed:@"trianglePointedUp.png"]];
        return v;
    }
    

提交回复
热议问题