MapKit: Change in Behaviour of addOverlay on iOS 16 / Xcode 14.0

Just after I have published my latest app project „Muvy“, a very nice tracking app for all outdoor activities, Apple released iOS 16 and Xcode 14.0. With big horror I had to notice that my app was not working properly with the new version of the operating system. All non-Apple maps were covering my tracks so that they were not visible anymore. What a pity. It turns out that Apple changed the behaviour of the quite central method addOverlay without notice.

The tracks shown on the map are created as MKPolyline objects, conforming to the MKOverlay protocol. Custom (non-Apple) maps are also overlays but of type MKTileOverlay. There are two principal methods to add overlays to the map (of type MKMapView):

  • addOverlay(_ overlay: MKOverlay) and
  • insertOverlay(_ overlay: MKOverlay, at index: Int)

The first one adds the overlay just on top of the others while with the second you could specify where in the overlay hierarchy you want to add the new one. With the second method you specify that the new overlay may be covered by the following ones in the overlays array. Overlays with higher index numbers may cover those with lower index numbers. At least, that was the situation before iOS 16.

To make sure that the tracks are always visible on the map I always used insertOverlay(_: at index 0) for adding the map tiles and addOverlay(_) for adding the polylines of the tracks. But on iOS 16, surprise surprise, addOverlay is not appending the array of overlays but inserts the overlay just before the tiles overlays. So the tiles overlays are covering all tracks in my app. Too bad.

To be honest there are also variants of the mentioned methods where you can specify the level („above roads“ or „above labels“) of insertion of the overlays. But in my case both types of overlays (tiles and polylines) are inserted in the same level.

Well, is this a bug or a feature? I don’t know. The documentation does not mention this change in behaviour.

Anyhow, the solution is to create my own method of insertion to make sure that the polylines cannot be covered by the map tiles:

Funny enough using

self.insertOverlay(overlay, at: self.overlays.count)

instead of

self.insertOverlay(overlay, above: last)

does not work. The overlay is still added before (below) the map tiles. „Stranger and stranger“, as Alice would say. I think I’d vote for a bug but with this extension I have a good workaround.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht.