The root of the problem seems to be that changing the center coordinate of the view doesn't take effect right away. The code that draws the arrow uses the x-coordinate of the center of the pin head as the distance at which to draw the arrow, but at the moment it gets that value the map view hasn't shifted yet. So it sets up the path in drawRect and then the map view shifts, resulting in the arrow being drawn in the wrong place.
The proper fix for this is probably to translate everything into the callout animation view's coordinates, so that the map shift would be irrelevant, but that's difficult to do since they don't overlap at all. Probably would need another invisible view that contained them both, and do it relative to that. I made the easy fix, which was to move the value of xPixelShift from adjustMapRegionIfNeeded to a class property and then apply it as a correction to the value returned from relativeParentXPosition.
The root of the problem seems to be that changing the center coordinate of the view doesn't take effect right away. The code that draws the arrow uses the x-coordinate of the center of the pin head as the distance at which to draw the arrow, but at the moment it gets that value the map view hasn't shifted yet. So it sets up the path in drawRect and then the map view shifts, resulting in the arrow being drawn in the wrong place.
The proper fix for this is probably to translate everything into the callout animation view's coordinates, so that the map shift would be irrelevant, but that's difficult to do since they don't overlap at all. Probably would need another invisible view that contained them both, and do it relative to that. I made the easy fix, which was to move the value of xPixelShift from adjustMapRegionIfNeeded to a class property and then apply it as a correction to the value returned from relativeParentXPosition.