¿Cómo se crea una animation de animation similar a la animation de eliminación de iPhone?

Actualmente estamos desarrollando una aplicación que contiene una serie de íconos. Queremos que los icons se muevan como las animaciones de eliminación de aplicaciones cuando se presionan. ¿Cuál sería la mejor manera de codificar esta secuencia de animation?

La respuesta de Vinzius es genial. Sin embargo, el bamboleo solo gira de 0 radianes a 0.08. Por lo tanto, el bamboleo puede parecer un poco desequilibrado. Si tiene este mismo problema, entonces puede agregar una rotation negativa y una positiva utilizando una CAKeyframeAnimation en lugar de una CABasicRotation:

- (CAAnimation*)getShakeAnimation { CAKeyframeAnimation* animation = [CAKeyframeAnimation animationWithKeyPath:@"transform"]; CGFloat wobbleAngle = 0.06f; NSValue* valLeft = [NSValue valueWithCATransform3D:CATransform3DMakeRotation(wobbleAngle, 0.0f, 0.0f, 1.0f)]; NSValue* valRight = [NSValue valueWithCATransform3D:CATransform3DMakeRotation(-wobbleAngle, 0.0f, 0.0f, 1.0f)]; animation.values = [NSArray arrayWithObjects:valLeft, valRight, nil]; animation.autoreverses = YES; animation.duration = 0.125; animation.repeatCount = HUGE_VALF; return animation; } 

Puede usar este método de animation para su vista o button como este.

 [self.yourbutton.layer addAnimation:[self getShakeAnimation] forKey:@""]; 

Si observamos la implementación de iOS un poco más cerca, hay dos cosas que hacen que el suyo sea un poco más realist que el código mencionado aquí:

  • Los íconos parecen tener un rebote y una rotation.
  • Cada ícono tiene su propio time; no todos están sincronizados

Me basé en las respuestas aquí (y con algo de ayuda de esta respuesta ) para agregar la rotation, el rebote y un poco de aleatoriedad a la duración de cada animation.

 #define kWiggleBounceY 4.0f #define kWiggleBounceDuration 0.12 #define kWiggleBounceDurationVariance 0.025 #define kWiggleRotateAngle 0.06f #define kWiggleRotateDuration 0.1 #define kWiggleRotateDurationVariance 0.025 -(void)startWiggling { [UIView animateWithDuration:0 animations:^{ [self.layer addAnimation:[self rotationAnimation] forKey:@"rotation"]; [self.layer addAnimation:[self bounceAnimation] forKey:@"bounce"]; self.transform = CGAffineTransformIdentity; }]; } -(CAAnimation*)rotationAnimation { CAKeyframeAnimation* animation = [CAKeyframeAnimation animationWithKeyPath:@"transform.rotation.z"]; animation.values = @[@(-kWiggleRotateAngle), @(kWiggleRotateAngle)]; animation.autoreverses = YES; animation.duration = [self randomizeInterval:kWiggleRotateDuration withVariance:kWiggleRotateDurationVariance]; animation.repeatCount = HUGE_VALF; return animation; } -(CAAnimation*)bounceAnimation { CAKeyframeAnimation* animation = [CAKeyframeAnimation animationWithKeyPath:@"transform.translation.y"]; animation.values = @[@(kWiggleBounceY), @(0.0)]; animation.autoreverses = YES; animation.duration = [self randomizeInterval:kWiggleBounceDuration withVariance:kWiggleBounceDurationVariance]; animation.repeatCount = HUGE_VALF; return animation; } -(NSTimeInterval)randomizeInterval:(NSTimeInterval)interval withVariance:(double)variance { double random = (arc4random_uniform(1000) - 500.0) / 500.0; return interval + variance * random; } 

Implementé este código en una UICollectionView que tenía 30 artículos rebotando y el performance era impecable en un iPad 2.

Traté de hacer algo así para una aplicación de iPad.

Intenté hacer algunas rotaciones (con CAAnimation) en la vista. Aquí hay un código de ejemplo que escribí:

  - (CAAnimation *) getShakeAnimation {

     CABasicAnimation * animation;
     CATransform3D transformar;

     // Crear la matriz de rotation
     transform = CATransform3DMakeRotation (0.08, 0, 0, 1.0);

     // Crea una animation básica para animar la transformación de la capa.
     animation = [CABasicAnimation animationWithKeyPath: @ "transform"];

     // Asigna la transformación como el valor de la animation
     animation.toValue = [NSValue valueWithCATransform3D: transform];

     animation.autoreverses = SÍ;  
     animation.duration = 0.1;  
     animation.repeatCount = HUGE_VALF;  

     animation de retorno;

 } 

Y debes tratar de aplicar esta a tu capa (con function: addAnimation). Aquí, la propiedad de conversión automática es alternar la orientación izquierda y derecha. Intente configurar otros valores para el ángulo y la duración.

Pero en mi caso tuve que agregar otros angularjs al método CATransform3DMakeRotation, dependiendo de la orientación de la capa inicial ^^

Buena suerte ! Vincent

SWIFT: –

 let transformAnim = CAKeyframeAnimation(keyPath:"transform") transformAnim.values = [NSValue(CATransform3D: CATransform3DMakeRotation(0.04, 0.0, 0.0, 1.0)),NSValue(CATransform3D: CATransform3DMakeRotation(-0.04 , 0, 0, 1))] transformAnim.autoreverses = true transformAnim.duration = (Double(indexPath.row)%2) == 0 ? 0.115 : 0.105 transformAnim.repeatCount = Float.infinity self.layer.addAnimation(transformAnim, forKey: "transform") 

C objective :-

 -(CAKeyframeAnimation *)wiggleView { CAKeyframeAnimation* animation = [CAKeyframeAnimation animationWithKeyPath:@"transform"]; CGFloat wobbleAngle = 0.04f; NSValue* valLeft = [NSValue valueWithCATransform3D:CATransform3DMakeRotation(wobbleAngle, 0.0f, 0.0f, 1.0f)]; NSValue* valRight = [NSValue valueWithCATransform3D:CATransform3DMakeRotation(-wobbleAngle, 0.0f, 0.0f, 1.0f)]; animation.values = [NSArray arrayWithObjects:valLeft, valRight, nil]; animation.autoreverses = YES; animation.duration = 0.125; animation.repeatCount = HUGE_VALF; return animation; } 

Reescribió la respuesta de Sebastien en Swift 3.

 let wiggleBounceY = 4.0 let wiggleBounceDuration = 0.12 let wiggleBounceDurationVariance = 0.025 let wiggleRotateAngle = 0.06 let wiggleRotateDuration = 0.10 let wiggleRotateDurationVariance = 0.025 func randomize(interval: TimeInterval, withVariance variance: Double) -> Double{ let random = (Double(arc4random_uniform(1000)) - 500.0) / 500.0 return interval + variance * random } func startWiggle(for view: UIView){ //Create rotation animation let rotationAnim = CAKeyframeAnimation(keyPath: "transform.rotation.z") rotationAnim.values = [-wiggleRotateAngle, wiggleRotateAngle] rotationAnim.autoreverses = true rotationAnim.duration = randomize(interval: wiggleRotateDuration, withVariance: wiggleRotateDurationVariance) rotationAnim.repeatCount = HUGE //Create bounce animation let bounceAnimation = CAKeyframeAnimation(keyPath: "transform.translation.y") bounceAnimation.values = [wiggleBounceY, 0] bounceAnimation.autoreverses = true bounceAnimation.duration = randomize(interval: wiggleBounceDuration, withVariance: wiggleBounceDurationVariance) bounceAnimation.repeatCount = HUGE //Apply animations to view UIView.animate(withDuration: 0) { view.layer.add(rotationAnim, forKey: "rotation") view.layer.add(bounceAnimation, forKey: "bounce") view.transform = .identity } } func stopWiggle(for view: UIView){ view.layer.removeAllAnimations() } 

Edité el código de paiego para adaptarse a mis necesidades: retroalimentación de animation de error visual sobre la acción del usuario (toque). Ocurre una vez: no es un movimiento constante como la edición de la aplicación SpringBoard edit animation.

 - (CAAnimation *)shakeAnimation { CAKeyframeAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:@"transform"]; CGFloat wobbleAngle = 0.06f; NSValue *valLeft; NSValue *valRight; NSMutableArray *values = [NSMutableArray new]; for (int i = 0; i < 5; i++) { valLeft = [NSValue valueWithCATransform3D:CATransform3DMakeRotation(wobbleAngle, 0.0f, 0.0f, 1.0f)]; valRight = [NSValue valueWithCATransform3D:CATransform3DMakeRotation(-wobbleAngle, 0.0f, 0.0f, 1.0f)]; [values addObjectsFromArray:@[valLeft, valRight]]; wobbleAngle*=0.66; } animation.values = [values copy]; animation.duration = 0.7; return animation; } 

Uso:

 [your_view.layer addAnimation:[self shakeAnimation] forKey:@""]; //do the shake animation your_view.transform = CGAffineTransformIdentity; //return the view back to original 

Espero que esto ayude a alguien más.

  func startWiggling() { deleteButton.isHidden = false guard contentView.layer.animation(forKey: "wiggle") == nil else { return } guard contentView.layer.animation(forKey: "bounce") == nil else { return } let angle = 0.04 let wiggle = CAKeyframeAnimation(keyPath: "transform.rotation.z") wiggle.values = [-angle, angle] wiggle.autoreverses = true wiggle.duration = randomInterval(0.1, variance: 0.025) wiggle.repeatCount = Float.infinity contentView.layer.add(wiggle, forKey: "wiggle") let bounce = CAKeyframeAnimation(keyPath: "transform.translation.y") bounce.values = [4.0, 0.0] bounce.autoreverses = true bounce.duration = randomInterval(0.12, variance: 0.025) bounce.repeatCount = Float.infinity contentView.layer.add(bounce, forKey: "bounce") } func stopWiggling() { deleteButton.isHidden = true contentView.layer.removeAllAnimations() } 

Mira este ejemplo de iOS SpingBoard