I have a map on my app that displays 2 kinds of annotations: locations and clusters of locations. When I zoom in on the a cluster the cluster is expanded to show the locations contained within the cluster. When these locations are added to the map the coordinate of their parent cluster is stored in the annotation object. What I want to do is have an animation so that, when these locations are added, they spread out from their parent cluster's location. Here is my code for mapView:didAddAnnotationViews:
- (void)mapView:(MKMapView *)mapView didAddAnnotationViews:(NSArray *)views
{
MKAnnotationView *aV;
for (aV in views)
{
if (([aV.annotation isKindOfClass:[PostLocationAnnotation class]]) && (((PostLocationAnnotation *)aV.annotation).hasParent))
{
CLLocationCoordinate2D startCoordinate = ((PostLocationAnnotation *)aV.annotation).parentCoordinate;
CGPoint startPoint = [ffMapView convertCoordinate:startCoordinate toPointToView:self.view];
CGRect endFrame = aV.frame;
aV.frame = CGRectMake(startPoint.x, startPoint.y, aV.frame.size.width, aV.frame.size.height);
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:1.00];
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
[aV setFrame:endFrame];
[UIView commitAnimations];
((PostLocationAnnotation *)aV.annotation).hasParent = NO;
}
}
}
This seems to make the map points fly in from some location far outside the focus of the view. Through debugging I have found that there is a massive discrepancy between the values for endFrame.origin and startPoint - for one particular aV, endFrame.origin comes up as (32657,21781) (both CGFloats) and startPoint comes up as (159.756256,247.213226) (again, both CGFloats). I am assuming that the endFrame.origin is the correct value as the points are ending up where I want them, they're just coming from somewhere far away. I've used the convertCoordinate:toPointToView: method in a lot of other parts of my code and had no problems. I've also tried multiplying the X and Y values of startPoint by various values but a single coefficient doesn't hold for every value of startPoint. Any idea what's going on?
The annotation view's frame seems to be based on the current zoom level and then offset from the screen coordinates. To compensate for this, offset the startPoint
by the annotationVisibleRect.origin
.
Also, when calling convertCoordinate:toPointToView:
, I think it's safer to convert to the map view's frame instead of self.view
since the map view might be a different size than the container view.
Try the following changes:
CGPoint startPoint = [ffMapView convertCoordinate:startCoordinate
toPointToView:ffMapView];
//BTW, using the passed mapView parameter instead of referencing the ivar
//would make the above line easier to re-use.
CGRect endFrame = aV.frame;
aV.frame = CGRectMake(startPoint.x + mapView.annotationVisibleRect.origin.x,
startPoint.y + mapView.annotationVisibleRect.origin.y,
aV.frame.size.width,
aV.frame.size.height);