I have used pin images in application instead of standard pin, now i want to give animation (dropping effect as it was with standard pins) to custom pins. How can i provide
Note that animating the annotation view in -mapView:didAddAnnotationViews:
causes strange effects when MKMapView.userTrackingMode
equals MKUserTrackingModeFollowWithHeading
. I just wish Apple made the drop animation available to the MKAnnotationView
class.
It feels also a lot cooler if you do not drop all the pins at once but drop each of them with a small delay so that it will look like there is a rain of pins effect. Similar to what Apple does natively. Use this:
- (void)mapView:(MKMapView *)mapView didAddAnnotationViews:(NSArray *)views {
MKAnnotationView *aV;
float delay = 0.00;
for (aV in views) {
CGRect endFrame = aV.frame;
aV.frame = CGRectMake(aV.frame.origin.x, aV.frame.origin.y - 430.0, aV.frame.size.width, aV.frame.size.height);
delay = delay + 0.01;
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDelay:delay];
[UIView setAnimationDuration:0.45];
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
[aV setFrame:endFrame];
[UIView commitAnimations];
}
}
Implement the following delegate method.
- (void)mapView:(MKMapView *)mapView didAddAnnotationViews:(NSArray *)views {
MKAnnotationView *aV;
for (aV in views) {
CGRect endFrame = aV.frame;
aV.frame = CGRectMake(aV.frame.origin.x, aV.frame.origin.y - 230.0, aV.frame.size.width, aV.frame.size.height);
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.45];
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
[aV setFrame:endFrame];
[UIView commitAnimations];
}
}
This worked well for me. Cant remember where i found it on here though
- (void)mapView:(MKMapView *)mapView didAddAnnotationViews:(NSArray *)views {
MKAnnotationView *aV;
for (aV in views) {
// Don't pin drop if annotation is user location
if ([aV.annotation isKindOfClass:[MKUserLocation class]]) {
continue;
}
// Check if current annotation is inside visible map rect, else go to next one
MKMapPoint point = MKMapPointForCoordinate(aV.annotation.coordinate);
if (!MKMapRectContainsPoint(self.mapView.visibleMapRect, point)) {
continue;
}
CGRect endFrame = aV.frame;
// Move annotation out of view
aV.frame = CGRectMake(aV.frame.origin.x, aV.frame.origin.y - self.view.frame.size.height, aV.frame.size.width, aV.frame.size.height);
// Animate drop
[UIView animateWithDuration:0.3 delay:0.03*[views indexOfObject:aV] options:UIViewAnimationCurveLinear animations:^{
aV.frame = endFrame;
// Animate squash
}completion:^(BOOL finished){
if (finished) {
[UIView animateWithDuration:0.05 animations:^{
aV.transform = CGAffineTransformMakeScale(1.0, 0.8);
}completion:^(BOOL finished){
if (finished) {
[UIView animateWithDuration:0.5 animations:^{
aV.transform = CGAffineTransformIdentity;
}];
}
}];
}
}];
}
}
Swift 3 drop animation
// animate annotation views drop
func mapView(_ mapView: MKMapView, didAdd views: [MKAnnotationView]) {
for annView in views {
// animate any annotation views except the user pin
if !(annView.annotation?.isKind(of: MKUserLocation.self))! {
let endFrame = annView.frame
annView.frame = endFrame.offsetBy(dx: 0, dy: -500)
UIView.animate(withDuration: 0.5, animations: {
annView.frame = endFrame
})
}
}