How To add custom View in map's Annotation's Callout's

后端 未结 6 1216
野的像风
野的像风 2020-11-28 02:38

Here is my code. I want to add my own custom callout view instead of iOS default. I know there is only left callout and right callout view, but I need to add a view tooltip

相关标签:
6条回答
  • 2020-11-28 02:58

    I have created a library to show custom callouts.

    DXCustomCallout-ObjC

    You can pass any custom view for the callout! It supports events for UIControls as well.

    Custom Callout

    0 讨论(0)
  • 2020-11-28 02:58

    You can use this library. It also provides a ready-to-use template for the callout view. Adds cool animations and an anchor view for your custom views.

    https://github.com/okhanokbay/MapViewPlus

    0 讨论(0)
  • 2020-11-28 03:00

    I just created a custom callout for my map view which avoids issues with the callout disappearing when tapped. Here is a Gist with the steps I took.

    0 讨论(0)
  • 2020-11-28 03:12

    Here is Best Example of CallOut View

    http://www.cocoacontrols.com/platforms/ios/controls/gikanimatedcallout

    http://www.cocoacontrols.com/platforms/ios/controls/multirowcalloutannotationview

    0 讨论(0)
  • 2020-11-28 03:13

    To the best answer above in Swift

    This can save some minutes to rewrite itself.

    !NOTE:

    There is one caveat which however can be easily fixed, your custom view will ignore touch events, because of mapView working with touches differently. Here's a quick fix:

    1) Subclass MKAnnotationView (or MKPinAnnotationView depends on what you need)

    2) in your mapView delegate

    func mapView(mapView: MKMapView, viewForAnnotation annotation: MKAnnotation) -> MKAnnotationView?
    

    use your subclass instead of MKAnnotationView/MKPinAnnotationView

    3) in your subclass .m file override two methods as following:

    override func hitTest(point: CGPoint, withEvent event: UIEvent?) -> UIView? {
    
        let hitView = super.hitTest(point, withEvent: event)
    
        if (hitView != nil)
        {
            self.superview?.bringSubviewToFront(self)
        }
    
        return hitView;
    
    }
    
    override func pointInside(point: CGPoint, withEvent event: UIEvent?) -> Bool {
    
        let rect = self.bounds
        var isInside = CGRectContainsPoint(rect, point)
    
        if(!isInside) {
            for view in self.subviews {
    
                isInside = CGRectContainsPoint(view.frame, point)
                break;
            }
        }
    
        return isInside
    }
    
    0 讨论(0)
  • 2020-11-28 03:18

    I had same problem and ended up doing following thing:

    When I receive mapView delegate callback

    -(void)mapView:(MKMapView *)mapView didSelectAnnotationView:(MKAnnotationView *)view
    

    (it's time when I want to show my custom CalloutView)

    I use view received as parameter *(MKAnnotationView )view (which is a pin view) and simply add my custom view to that pin view using

     [view addSubview:customView];
    

    It will add your custom view on top of that pin view so if we want it to be above pin we have to change custom view center property like this:

    CGRect customViewRect = customView.frame;
            CGRect rect = CGRectMake(-customViewRect.size.width/2, -customViewRect.size.height-7, customViewRect.size.width, customViewRect.size.height);
            customView.frame = rect;
    [view addSubview:customView];
    

    In my case it looks like this

    enter image description here

    !NOTE:

    There is one caveat which however can be easily fixed, your custom view will ignore touch events, because of mapView working with touches differently. Here's a quick fix:

    1) Subclass MKAnnotationView (or MKPinAnnotationView depends on what you need)

    2) in your mapView delegate

    - (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation
    

    use your subclass instead of MKAnnotationView/MKPinAnnotationView

    3) in your subclass .m file override two methods as following:

    - (UIView*)hitTest:(CGPoint)point withEvent:(UIEvent*)event
    {
        UIView* hitView = [super hitTest:point withEvent:event];
        if (hitView != nil)
        {
            [self.superview bringSubviewToFront:self];
        }
        return hitView;
    }
    
    - (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent*)event
    {
        CGRect rect = self.bounds;
        BOOL isInside = CGRectContainsPoint(rect, point);
        if(!isInside)
        {
            for (UIView *view in self.subviews)
            {
                isInside = CGRectContainsPoint(view.frame, point);
                if(isInside)
                    break;
            }
        }
        return isInside;
    }
    

    All done!

    0 讨论(0)
提交回复
热议问题