mkmapviewmkoverlaymkoverlaypathrenderermkcircle

Scroll MKMapView Underneath Circle Drawn MKMapView


UPDATE

I need to draw a circle onto a MKMapView, something where I can get the radius of the circle and it's center coordinate. However, I would also like the circle to be a subview of the MKMapView, so that the map view can scroll underneath the circle, updating its center coordinate as the map moves and updating its radius as the map is zoomed in and out.

Does anyone know how I might be able to accomplish this?


This is the original wording of the question

I've drawn a circle onto a MKMapView using the code below:

- (void)viewDidLoad
{
    [super viewDidLoad];

    self.locationManager = [[CLLocationManager alloc] init];
    self.locationManager.delegate = self;

    self.region = [MKCircle circleWithCenterCoordinate:self.locationManager.location.coordinate radius:kViewRegionDefaultDistance];
    [self.mapView addOverlay:self.region];
}

- (MKOverlayPathRenderer *)mapView:(MKMapView *)map viewForOverlay:(id <MKOverlay>)overlay
{
    MKCircleRenderer *region = [[MKCircleRenderer alloc] initWithOverlay:overlay];
    region.strokeColor = [UIColor blueColor];
    region.fillColor = [[UIColor blueColor] colorWithAlphaComponent:0.4];
    return region;
}

This works and produces a circle on the map view. However, when I scroll the map view, the circle moves with it. I would like the circle to remain stationary and have the map view scroll underneath the circle.

Is is important to note that I will need to get the center coordinate and radius of the circle in order to create a region. For that reason, I cannot simply draw a UIView on top of the MKMapView, as I would have no way to get the radius in meters of the UIView.


Solution

  • I solved it!

    Step 1:

    I created a UIView and added it as a subview to the map view. It is important to note that I made sure to center the UIView on the map view. This is important because you will use the centerCoordinate property of the MKMapView to calculate the radius.

    self.region = [[UIView alloc] initWithFrame:centerOfMapViewFrame];
    self.region.contentMode = UIViewContentModeRedraw;
    self.region.userInteractionEnabled = NO;
    self.region.alpha = 0.5;
    self.region.layer.cornerRadius = widthOfView/2;
    self.region.backgroundColor = [UIColor blueColor];
    
    [self.mapView addSubview:self.region];
    

    The image below shows the circular UIView added as a subview to the mapView.

    enter image description here

    Step 2:

    Calculate the radius based off of the center coordinate of map view and the edge coordinate of the UIView.

    CLLocationCoordinate2D edgeCoordinate = [self.mapView convertPoint:CGPointMake((CGRectGetWidth(self.region.bounds)/2), 0) toCoordinateFromView:self.region]; //self.region is the circular UIView
    
    CLLocation *edgeLocation = [[CLLocation alloc] initWithLatitude:edgeCoordinate.latitude longitude:edgeCoordinate.longitude];
    CLLocation *centerLocation = [[CLLocation alloc] initWithLatitude:self.mapView.centerCoordinate.latitude longitude:self.mapView.centerCoordinate.longitude];
    
    CGFloat radius = [edgeLocation distanceFromLocation:centerLocation]; //is in meters
    

    The image below shows an annotation on the edgeLocation and on the centerLocation.

    enter image description here