cocoa-touch ios-4.2 mkannotationview mkpinannotationview mapkit

cocoa touch - ¿Cómo puedo animar MKAnnotationView drop?



cocoa-touch ios-4.2 (5)

Implemente el método delegado didAddAnnotationViews y realice la animación usted mismo:

- (void)mapView:(MKMapView *)mapView didAddAnnotationViews:(NSArray *)annotationViews { for (MKAnnotationView *annView in annotationViews) { CGRect endFrame = annView.frame; annView.frame = CGRectOffset(endFrame, 0, -500); [UIView animateWithDuration:0.5 animations:^{ annView.frame = endFrame; }]; } }

Tengo una MKAnnotationView personalizada donde configuro mi imagen en viewForAnnotation. ¿Cómo puedo animar su caída como puedo con MKPinAnnotationView?

Mi código es

- (MKAnnotationView *)mapView:(MKMapView *)map viewForAnnotation:(id <MKAnnotation>)annotation { static NSString *AnnotationViewID = @"annotationViewID"; MKAnnotationView *annotationView = (MKAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:AnnotationViewID]; if (annotationView == nil) { annotationView = [[[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:AnnotationViewID] autorelease]; } annotationView.image = [UIImage imageNamed:@"blah.png"]; annotationView.annotation = annotation; return annotationView; }


Un problema con el código anterior de Anna Karenina es que no se trata de cuándo se agregan las anotaciones a continuación, donde el usuario está mirando el momento. Esas anotaciones flotarán en el aire antes de caer porque se moverán al mapa visible del usuario.

Otra es que también deja caer el punto azul de la ubicación del usuario. Con este código a continuación, maneja la ubicación del usuario y grandes cantidades de anotaciones de mapa fuera de la pantalla. También agregué un buen rebote;)

- (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.5 delay:0.04*[views indexOfObject:aV] options: UIViewAnimationOptionCurveLinear 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.1 animations:^{ aV.transform = CGAffineTransformIdentity; }]; } }]; } }]; } }


@mrAlek responde en Swift:

func mapView(mapView: MKMapView!, didAddAnnotationViews views: [AnyObject]!) { println("didAddAnnotationViews()") var i = -1; for view in views { i++; let mkView = view as! MKAnnotationView if view.annotation is MKUserLocation { continue; } // Check if current annotation is inside visible map rect, else go to next one let point:MKMapPoint = MKMapPointForCoordinate(mkView.annotation.coordinate); if (!MKMapRectContainsPoint(self.mapView.visibleMapRect, point)) { continue; } let endFrame:CGRect = mkView.frame; // Move annotation out of view mkView.frame = CGRectMake(mkView.frame.origin.x, mkView.frame.origin.y - self.view.frame.size.height, mkView.frame.size.width, mkView.frame.size.height); // Animate drop let delay = 0.03 * Double(i) UIView.animateWithDuration(0.5, delay: delay, options: UIViewAnimationOptions.CurveEaseIn, animations:{() in mkView.frame = endFrame // Animate squash }, completion:{(Bool) in UIView.animateWithDuration(0.05, delay: 0.0, options: UIViewAnimationOptions.CurveEaseInOut, animations:{() in mkView.transform = CGAffineTransformMakeScale(1.0, 0.6) }, completion: {(Bool) in UIView.animateWithDuration(0.3, delay: 0.0, options: UIViewAnimationOptions.CurveEaseInOut, animations:{() in mkView.transform = CGAffineTransformIdentity }, completion: nil) }) }) } }


La respuesta de @ MrAlek en Swift 2:

func mapView(mapView: MKMapView, didAddAnnotationViews views: [MKAnnotationView]) { print(__FUNCTION__) var i = -1; for view in views { i++; if view.annotation is MKUserLocation { continue; } // Check if current annotation is inside visible map rect, else go to next one let point:MKMapPoint = MKMapPointForCoordinate(view.annotation!.coordinate); if (!MKMapRectContainsPoint(self.mapView.visibleMapRect, point)) { continue; } let endFrame:CGRect = view.frame; // Move annotation out of view view.frame = CGRectMake(view.frame.origin.x, view.frame.origin.y - self.view.frame.size.height, view.frame.size.width, view.frame.size.height); // Animate drop let delay = 0.03 * Double(i) UIView.animateWithDuration(0.5, delay: delay, options: UIViewAnimationOptions.CurveEaseIn, animations:{() in view.frame = endFrame // Animate squash }, completion:{(Bool) in UIView.animateWithDuration(0.05, delay: 0.0, options: UIViewAnimationOptions.CurveEaseInOut, animations:{() in view.transform = CGAffineTransformMakeScale(1.0, 0.6) }, completion: {(Bool) in UIView.animateWithDuration(0.3, delay: 0.0, options: UIViewAnimationOptions.CurveEaseInOut, animations:{() in view.transform = CGAffineTransformIdentity }, completion: nil) }) }) } }


@ Respuesta de MrAlek para swift3

optional func mapView(_ mapView: MKMapView, didAdd views: [MKAnnotationView]) { print(#function) var i = -1; for view in views { i += 1; if view.annotation is MKUserLocation { continue; } // Check if current annotation is inside visible map rect, else go to next one let point:MKMapPoint = MKMapPointForCoordinate(view.annotation!.coordinate); if (!MKMapRectContainsPoint(self.mapView.visibleMapRect, point)) { continue; } let endFrame:CGRect = view.frame; // Move annotation out of view view.frame = CGRect(origin: CGPoint(x: view.frame.origin.x,y :view.frame.origin.y-self.view.frame.size.height), size: CGSize(width: view.frame.size.width, height: view.frame.size.height)) // Animate drop let delay = 0.03 * Double(i) UIView.animate(withDuration: 0.5, delay: delay, options: UIViewAnimationOptions.curveEaseIn, animations:{() in view.frame = endFrame // Animate squash }, completion:{(Bool) in UIView.animate(withDuration: 0.05, delay: 0.0, options: UIViewAnimationOptions.curveEaseInOut, animations:{() in view.transform = CGAffineTransform(scaleX: 1.0, y: 0.6) }, completion: {(Bool) in UIView.animate(withDuration: 0.3, delay: 0.0, options: UIViewAnimationOptions.curveEaseInOut, animations:{() in view.transform = CGAffineTransform.identity }, completion: nil) }) }) } }