MKMapView ignoring Safe Area on iOS 11 and iPhone X
Asked Answered
P

5

9

I'm trying to migrate a app to iOS 11 and for days I'm stuck with one ugly UI bug after the other. This time: MKMapView. I have a bunch of buttons which I pinned to the Safe Area Layout Guides and everything is working fine - except the MKMapView.

It completely ignores the Safe Area and therefore the compass and legal buttons are hidden under bars or my own UI elements. To verify, I created a new project with only one plain UIViewController. Then I added a MKMapView and configured custom "additionalSafeAreaInsets" which are indeed completely ignored.

The worse is probably that even with just the MKMapView, the legal label looks horribly wrong on iPhone X.

Question: is there any way I can inset the legal label and the compass to not get hidden by custom views?

enter image description here

Polinski answered 23/11, 2017 at 9:39 Comment(3)
take mapview inside uiview then ?Shani
This seems to have stopped working from iOS 11.1. I have tried all solutions I have found, but can't get it to work either. I have also seen a radar on this, so I guess it's an iOS bug that will be fixed.Undoing
are you using constraints and auto layout?Ulises
R
1

The correct approach is to set additionalSafeAreaInsets of the view controller that contains the MKMapView. Doing so will allow you to adjust both the compass and "Legal" label as needed to accommodate for custom views on top of the map.

Redoubtable answered 5/6, 2018 at 20:23 Comment(2)
interesting, @dbart, where did you get that info?Cola
Safe area insets are used to adjusts content offset inside scroll views (think UITableView and UICollectionView). An MKMapView is just a more complex scroll view that uses these insets to align floating content like "Legal" label and compass.Redoubtable
P
1

The only solution worked for me

  1. Disable compass in the MapView
  2. Create a new Compass button manually and simply put it wherever you like it

Here is an example

    @IBOutlet weak var mapView: MKMapView! {
    didSet {
        let userTrackingButton = MKUserTrackingButton(mapView: mapView)
        userTrackingButton.layer.position = CGPoint(x: 100, y: 100)
        userTrackingButton.backgroundColor = UIColor.white

        let compassButton = MKCompassButton(mapView: mapView)
        compassButton.layer.position = CGPoint(x: 100, y: 150)
        compassButton.compassVisibility = .adaptive

        mapView.delegate = self
        mapView.showsUserLocation = true
        mapView.setUserTrackingMode(.follow, animated: true)
        mapView.addSubview(userTrackingButton)
        mapView.addSubview(compassButton)
    }
}
Pirogue answered 13/6, 2018 at 22:28 Comment(1)
Thanks! Looks like this one is the most correct since iOS11.Cola
C
1

Looking into this for one of my own projects, looks like interface builder has a solution for this:

On the map view, select "Preserve Superview Margins" and "Safe area relative Margins"

On the map view, select "Preserve Superview Margins" and "Safe area relative Margins" and the legal + compass will be positioned correctly.

Cockrell answered 2/12, 2018 at 15:40 Comment(0)
T
1

Another solution to this issue is to use the directionalLayoutMargins property of UIView available in iOS 11.0+. This lets you specify the margins of a view before the content of any subviews (in this case the Legal notes) is drawn.

mapView.directionalLayoutMargins = NSDirectionalEdgeInsetsMake(0, 0, 25, 0);

Trichloroethylene answered 3/5, 2020 at 14:43 Comment(1)
Anyone else ever find themselves looking for the solution to a problem, only to find they've already recently solved it, but somehow completely forgotten this fact. :-/Trichloroethylene
A
0

In Xcode 13.2, iOS 15.4,select the view controller in Interface Builder and open the Attributes Inspector. In the section "Extend Edges", clear "Under Top Bars" and "Under Bottom Bars" check boxes.

Ardussi answered 27/4, 2022 at 6:32 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.