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

xxtesaxx
  • 6,175
  • 2
  • 31
  • 50

5 Answers5

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.

dbart
  • 5,468
  • 2
  • 23
  • 19
  • interesting, @dbart, where did you get that info? – Oleg Shanyuk Jun 25 '18 at 16:16
  • 1
    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. – dbart Jun 26 '18 at 15:45
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)
    }
}
Vagif
  • 354
  • 3
  • 7
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.

danwkennedy
  • 121
  • 10
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);

jt_uk
  • 1,362
  • 1
  • 15
  • 17
  • 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. :-/ – jt_uk Jun 30 '20 at 23:15
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.

Phil
  • 1,030
  • 1
  • 16
  • 22