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:
- Change the position of the compass
- 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.
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.
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.
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:
Inside the app it looks like this: