Anthony Mattox
Anthony Mattox

Reputation: 7118

MKMapView Content Insets with Navigation Bar

I'm experiencing a strange issue with MKMapView placed in a view with a navigation bar. Given a UIScrollView in the same situation, whose width, height, and center are constrained to it's superview (the view controller's view object) the insets will be adjusted if the controller's automaticallyAdjustsScrollViewInsets property is set to YES, and not if set to NO. That's great. I can not find this documented anywhere, but the map view seems to do the same thing, but it's not possible to disable it. Setting automaticallyAdjustsScrollViewInsets has no effect.

In brief(ish):

In the image below, the small back square is centered within the view, regardless of navigation bar. The map view is also constrained to be exactly the size of the view (it extends behind the nav bar). The location of the map view was set to be the current location (also indicated by the blue circle) so I would expect them to match, but they are off by half the combined height of status and navigation bars.

Is there an explanation for this behavior, and a way to get it to work as expected?

Screenshot of MKMapView acting a fool

This is very strange because an MKMapView is not a subclass of a UIScrollView but it is behaving like one in this case. That's not completely unreasonable, but I would expect the auto adjusting insets to work consistently on a map view and a scroll view.

Workaround

Something awful like this would 'solve the problem':

MKCoordinateRegion region = MKCoordinateRegionMake(self.coordinate, MKCoordinateSpanMake(0.008, 0.008));
MKMapRect mapRect = MKMapRectForCoordinateRegion(region);
[self.mapView setVisibleMapRect:mapRect edgePadding:UIEdgeInsetsMake(0, 0, 64, 0) animated:YES];

Either adjusting the bottom inset as well, or adding a negative inset on the top gets things lined up, but it would break if this behavior of the map view changes, or if the view controller is presented without a navigation bar, or if there is a stiff breeze. It also erodes my confidence in pulling correct coordinates back out of the map view.

Upvotes: 13

Views: 3118

Answers (2)

incanus
incanus

Reputation: 5128

MKMapView does indeed sit under the navigation bar, but automatically uses a housing view controller's topLayoutGuide to shift annotations and the compass view, etc. down from under it.

You should make sure that your own views take this into account in their autolayout code.

Upvotes: 6

Mike
Mike

Reputation: 9835

If you take a look at this, you can see that the mapview is very likely not sitting under the navigation bar, as you think. It is sitting between the bottom of the nav bar and the bottom of the superview.

On another note, the navigation bar is translucent by default, so if the mapview was really sitting under the nav bar you would be able to see through it, assuming you didn't disable the default nav bar behavior.

enter image description here

Upvotes: -1

Related Questions