Setting a MapView's center coordinate does not

2019-04-11 21:04发布

The Problem

I have a view that includes a full-screen MKMapView. The bottom half of the MapView is covered with a TableView that has translucent cells so that the map shows through.

User location annotation blocked by TableView

When I center on an annotation coordinate, the current location for example, the annotation view is blocked by the TableView.

- (void)centerOnCurrentLocation
{
    MKCoordinateRegion region = MKCoordinateRegionMakeWithDistance(self.locationManager.location.coordinate, 50000, 50000);
    [self.mapView setRegion:[self.mapView regionThatFits:region] animated:YES];
}

Attempted Solution

I first tried to programmatically shift the map to offset the center, shifting the annotation up. This approach works if I turn off animation, though it's not a simple solution. Nor do I want to turn off animation.

Instead I thought that if I extend the MapView off the top of the screen by the same height as the TableView the center of the MapView would be exactly where I want it. It doesn't work! When I set the center coordinate on the larger MapView the annotation still appears in the center of the screen, not in the center of the larger MapView. It seems like MKMapView is using the view's visible region when calculating its center.

Enlarged MapView

This is what I would expect to see when I center on current location using the enlarged MapView.

This is what I want to see when I center on current location.

If only MKMapView had a centerOffset property that allowed you to shift the center by some CGPoint.

Does anybody have a simple, elegant solution to offset a MapView's center?

1条回答
神经病院院长
2楼-- · 2019-04-11 22:08

Just to clarify on my comment, you can use setVisibleMapRect: edgePadding: to create the offset you want. You will need to put it in the mapView delegate method regionDidChangeAnimated: this will fire anytime the region changes on your map so you need to wrap your code with a flag to know when to apply the offset or it can be applied multiple times. Here is what you need to do:

- (void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated{

    if (!self.mapInsetsSet) {
        self.mapInsetsSet=TRUE;
        [self.myMapView setVisibleMapRect:self.myMapView.visibleMapRect edgePadding:UIEdgeInsetsMake(10, 0, 0, 0) animated:YES];
    }

}

In the above code, mapInsetsSet is just a bool that you can set elsewhere to control when to apply the offset. Also, you will need to adjust the UIEdgeInsetsMake to the desired offset.

查看更多
登录 后发表回答