10
votes

I have an app where i'm creating a views hierarchy where i have a mapview and a tableview. The mapview is under the tableview and is visible on the top when the table vertical offset is negative. The Structure of the view is something like this:

screen mockup

Where the yellow is the map, the green on the top is a navigation bar and green at the bottom is the tableview.

When you scroll the table view the map should show the user location at the center of the visible portion of the map.

The problem i'm experiencing is that when i apply the parallax the map center is not the location i'm setting. This is a screenshot from a sample project that i did to isolate the problem. The center coordinate is Buckingham Palace.

sample project screenshot

The orange square is a debug view that is at the center of the mapView (where the center coordinate should be). I'm sure that the parallax effect it's correct.

The structure of my view hierarchy regarding the mapView in the sample project is represented in the following image. The position of the views reflects the screenshot above.

enter image description here

The following code is used to set the frame.origin.y value of the mapContainerView. I'm using the mapContainerView to avoid to touch the frame of the mapView to perform the parallax effect. The mapView is a subview of the mapContainerView (at the begin I was using a translation on the mapView but i changed the code to try to isolate the cause of this problem)

self.mapViewContainer.frame = CGRectMake(0, self.currentY, CGRectGetWidth(self.view.frame), CGRectGetHeight(self.view.frame));

if (!CGRectEqualToRect(self.mapViewContainer.bounds, self.mapView.bounds)) {
    self.mapView.bounds = CGRectMake(0,
                                     0,
                                     CGRectGetWidth(self.mapViewContainer.bounds),
                                     CGRectGetHeight(self.mapViewContainer.bounds));

    self.mapView.center = CGPointMake(CGRectGetMidX(self.mapViewContainer.bounds),
                                      CGRectGetMidY(self.mapViewContainer.bounds));
}

self.squareView.bounds = CGRectMake(0, 0, 22.0f, 22.0f);
self.squareView.center = CGPointMake(CGRectGetMidX(self.mapViewContainer.bounds),
                                     CGRectGetMidY(self.mapViewContainer.bounds));

My guess is that the status bar is doing something to the mapView. If you look to the simulator screenshot you can notice how the center coordinate are exactly located at the center of the vertical space that goes from the status bar to the bottom of the mapView.

enter image description here

If i set the center of the coordinate in the viewDidLoad, after the creation of the map (when it's frame is CGRectZero) the center of the map is correctly in the center of the map.

If i change it later (for example with a timer that, to simulate the location update, sets the same map region that it is set in the viewDidLoad) the map view decide to change the center as showed above.

I can't find any method to disable or change this behaviour. Am I doing something wrong here? I'm working on a workaround but i'm curious to know if someone know what i'm missing here.

This is the code of the sample project i created to reproduce the problem in an isolate scenario. https://gist.github.com/lucabartoletti/a5f103cb74a3edb178d6

Some restriction i have.

  • The map must be big enough to cover the window frame
  • The status bar must be visible
1

1 Answers

0
votes

Try this:

_mapView.delegate = self;

func mapView(mapView: MKMapView!, didUpdateUserLocation 
        userLocation: MKUserLocation!) {
    mapView.centerCoordinate = userLocation.location.coordinate
}