The regionSpan can change slightly #20

Closed
plu opened this Issue Feb 15, 2014 · 8 comments

Comments

Projects
None yet
3 participants

plu commented Feb 15, 2014

Hi Claus,

I've noticed the clusters to rearrange when I programmtically change the region of the map. When the user is moving the map by hand, everything is fine and the clusters stay the same. But whenever I use setCenterCoordinate:animated: or setRegion:animated:, the annotation clusters rearrange themselves. I've noticed that the CCHMapClusterController stores the MKCoordinateSpan right before the region is changed, and compares it to the new span afterwards.
In the documentation of setCenterCoordinate:animated: Apple promises:

Changing the center coordinate centers the map on the
new coordinate without changing the current zoom level.

This is true from a human point of view. At least I cannot see the map zoom in. But the span value changes slightly. I've created a branch here to illustrate the issue: https://github.com/plu/CCHMapClusterController/compare/regionSpanBeforeChange

There are three commits. If you reset to the first one (5451b4f) and tap on any of the annotations, you'll see that while it's being centered, the clusters are rearranged. The other two commits are not meant to be a proper fix. Just to illustrate the difference.

Do you have any idea how to properly fix this?

Best regards,
plu

Owner

choefele commented Feb 15, 2014

Thanks for reporting this issue!

It's expected that updateAnnotationsWithCompletionHandler: gets called when you call setCenterCoordinate:animated:. Surprisingly, though, the cell size in map point units returned by CCHMapClusterControllerMapLengthForLength changes. That's why the clusters rearrange.

I have no idea why the cell size changes when calling setCenterCoordinate:animated: but not when panning the map through use interactions.

If you print out the cell size returned by CCHMapClusterControllerMapLengthForLength, you can see that the cell size is bigger when selecting a cluster further north and smaller when selecting one that's further south.

Really strange.

plu commented Feb 16, 2014

Thanks for your answer!

I have the feeling, that Apple is internally using setRegion:animated: whenever you use setCenterCoordinate:animated:. There it says:

Changing just the center coordinate of the region can still cause the span values to change
implicitly. The span values might change because that the distances represented by a span
change at different latitudes and longitudes and the map view may need to adjust the span
to account for the new location. If you want to change the center coordinate without
changing the zoom level, use the setCenterCoordinate:animated: instead.

But the last part does not seem to be true, really weird. I've checked OpenRadar, if this is a known issue, but no luck so far.

@choefele choefele added the bug label Feb 17, 2014

Owner

choefele commented Feb 19, 2014

You are right, the zoom changes. It seems to be a problem specific to iOS 7. I can't reproduce this on iOS 6, but I can on iOS 7 and 7.1 Beta 5 (tested on simulator).

As a workaround, I suggest the following code, which avoids zooming in my tests:

    CLLocationCoordinate2D location = CLLocationCoordinate2DMake(52.526221, 13.397829);
    MKMapPoint point = MKMapPointForCoordinate(location);
    MKMapRect rect = [self.mapView visibleMapRect];
    rect.origin.x = point.x - rect.size.width * 0.5;
    rect.origin.y = point.y - rect.size.height * 0.5;
    [self.mapView setVisibleMapRect:rect animated:YES];

@plu Could you please have a look whether this solves your problem?

plu commented Feb 20, 2014

This does fix my problem, thanks a lot! You can close this ticket, if you want to :).

Maybe we should file a Radar then for iOS 7? The other day I was already looking into OpenRadar for similar issues, but could not identify any.

@choefele choefele added question and removed bug labels Feb 20, 2014

Owner

choefele commented Feb 20, 2014

I added a code example for this to the documentation. Thanks again for reporting this issue.

@choefele choefele closed this Feb 20, 2014

mikrobi commented Apr 9, 2015

I'm still facing issues even with using setVisibleMapRect:animated:. In my app I want to center the map whenever the user selects an annotation. In general this works fine, but in case of a big zoom level, the map view somehow ignores the CGRect that I pass to setVisibleMapRect:animated:. After setting the rect, I end up with a bigger rect than I originally passed in. I couldn't find any solutions so far. Have you experienced a similar behaviour?

mikrobi commented Apr 10, 2015

I've done some testing with mapRectThatFits:(MKMapRect)mapRect before setting the rect via setVisibleMapRect:(MKMapRect)mapRect animated:(BOOL)animate like described in the docs.

According to the Apple Docs, I assume that the return value of mapRectThatFits:(MKMapRect)mapRect should match the rect that will be applied internally when using setVisibleMapRect:(MKMapRect)mapRect animated:(BOOL)animate

The funny (or annoying) thing is that the calculated rect via

MKMapRect rect = [self.mapView visibleMapRect];
rect.origin.x = point.x - rect.size.width * 0.5;
rect.origin.y = point.y - rect.size.height * 0.5;

never matches the rect returned by [mapView mapRectThatFits:rect]. The size always differs slightly by random values below 0.5. Probably caused by because of all the internal calculations, rounding and conversions by MapKit?

I haven't found any cool way to set the center coordinate or change the visible map rect by not (slightly) changing mapView.region.span.longitudeDelta which is used in CCHMapClusterController to determine if the zoom level changed after changing the map view's region.

I was thinking about adding something like a "zoom change tolerance" so that we ignore marginal zoom changes and only re-cluster when the zoom changed significantly. @choefele what do you think? Should we re-open this issue?

mikrobi commented Apr 10, 2015

Hmm, the "zoom change tolerance" prevents the CCHMapClusterController from undesired deselections. But then it might happen, that a selected annotation disappears because it gets merged into a cluster. This is caused because a marginal change of longitudeDelta might trigger a "heavy" cluster re-odering like described in #82. Seems like these issues are highly coupled.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment