2010-09-13 11 views
30

Actualmente estamos desarrollando una aplicación que contiene una serie de iconos. Queremos que los iconos 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 animación?Cómo se crea una animación de ondulación similar a la animación de eliminación de iphone

+3

posible duplicado de [cómo crear el efecto de icono de wobbling de iphone?] (Http://stackoverflow.com/questi ons/929364/how-to-create-iphones-wobbling-icon-effect) – kennytm

+0

Echa un vistazo a esto: [Wobble Effect] (https://github.com/rajendrahn/ShakeAnimation) – Raj

Respuesta

11

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

He intentado hacer algunas rotaciones (con CAAnimation) a la vista. Aquí es un ejemplo de código que escribí:

- (CAAnimation*)getShakeAnimation { 

    CABasicAnimation *animation; 
    CATransform3D transform; 

    // Create the rotation matrix 
    transform = CATransform3DMakeRotation(0.08, 0, 0, 1.0); 

    // Create a basic animation to animate the layer's transform 
    animation = [CABasicAnimation animationWithKeyPath:@"transform"]; 

    // Assign the transform as the animation's value 
    animation.toValue = [NSValue valueWithCATransform3D:transform]; 

    animation.autoreverses = YES; 
    animation.duration = 0.1; 
    animation.repeatCount = HUGE_VALF; 

    return animation; 

}

y usted debe tratar de aplicar éste a su capa (con la función: addAnimation). Aquí, la propiedad de reenvío automático consiste en alternar la orientación izquierda y derecha. Intenta establecer otros valores para el ángulo y la duración.

Pero en mi caso he tenido que añadir otros ángulos con el método CATransform3DMakeRotation, dependiendo de la orientación inicial de la capa ^^

buena suerte! Vincent

+1

¡Eres increíble amigo mío! !! – user446718

31

La respuesta de Vinzius es muy buena. Sin embargo, la oscilación solo gira de 0 radianes a 0.08. Por lo tanto, la oscilación puede parecer un poco desequilibrada. Si obtiene este mismo problema, entonces es posible que desee añadir tanto una negativa y una rotación positiva mediante el uso de un CAKeyframeAnimation en lugar de un 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;  
} 

Usted puede utilizar este método de animación para la vista o el botón de esta manera.

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

Gran animación, gracias. Intenta las dos respuestas, ambas son excelentes, esta es mejor para mi opinión. – shannoga

+0

cómo agregarlo a mi vista o botón ..? – g212gs

14

En cuanto a la aplicación de iOS un poco más cerca, hay dos cosas que hacen de ellos un poco más realista que el código se mencionan aquí:

  • Los iconos parecen tener un rebote, así como una
  • rotación
  • Cada icono tiene su propio tiempo - no todos ellos están sincronizados

me basé en las respuestas aquí (y con la ayuda de este answer) para agregar la rotación, el rebote y un poco de aleatoriedad a la duración de cada animación.

#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; 
} 

he implementado este código en un UICollectionView cuales tenían 30 artículos de rebote y la actuación fue impecable en un iPad 2.

9

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") 

Objetivo C : -

-(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; 
} 
0

Código de paiego editado para satisfacer mis necesidades: retroalimentación visual de animación de error sobre la acción del usuario (toque). Sucede una vez: no es un movimiento constante como la animación de ondulación de edición de la aplicación SpringBoard.

- (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.

2

respuesta de Reescribió 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() 
} 
1
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 esta iOS SpingBoard example

Cuestiones relacionadas