1024kilobyte

View Original

Custom compass position in MKMapView

For map views in native iOS apps MKMapView is my first choice. While implementing an map based app I came to the point where the compass was showing under a menu component. This is because the default compass position is in the top right corner of the map view. So there were two solutions to the problem:

  1. Change the position of the compass
  2. Remove the compass and implement a custom one

Although the second option sounded tempting, the first one seemed to be the obvious choice. But then I learned that the MKMapView doesn't let you do anything with its compass besides the possibility to show or hide it via the 'showCompass' function. I was surprised by this fact, because on the iOS default map app you can see the compass on a custom position.

Custom compass position in apple maps app

Solving the puzzle

By analyzing the issue I saw the compass is a subview of the map with a custom class called 'MKCompassView'. As the class itself is private API it is not exposed for external use, but I don't need that. To set a new position for the compass I subclassed the MKMapView component and overrode the layoutSubviews function to change the frame of the MKCompassView.

See this content in the original post

As you can see this is really easy. Then I just had tell the app to use the map view subclass as the map component and my problem was solved.

App showing the compass at a custom position on a MKMapView

Make it useful

Then I realized that a static position isn't good at all in my case, you will see the reason later. So I made the position variable and added a simple animation. The final code looks like this:

See this content in the original post

Inside the app it looks like this:

Animated custom compass position on a MKMapView