Scroll MKMapView Underneath Circle Drawn MKMapView

289 views Asked by At

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.

2

There are 2 answers

1
tentmaking On BEST ANSWER

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

0
Dan Burkhardt On

Swift 4.2/5 adaptation

let edgeCoordinate = self.mapView.convert(mapView.center, toCoordinateFrom: overlayView)

let edgeLocation: CLLocation = .init(latitude: edgeCoordinate.latitude, longitude: edgeCoordinate.longitude)

let centerLocation: CLLocation = .init(latitude: mapView.centerCoordinate.latitude, longitude: mapView.centerCoordinate.longitude)

let radius = edgeLocation.distance(from: centerLocation)

// do something with the radius

Where overlayView is the custom circle you created to represent radius