2010-09-13 12 views
30

Attualmente stiamo sviluppando un'applicazione che contiene una serie di icone. Vogliamo che le icone si muovano come le animazioni di eliminazione delle app quando vengono premute. Quale sarebbe il modo migliore per codificare questa sequenza di animazione?Come si crea un'animazione di animazione simile all'eliminazione di un iphone animazione

+3

possibile duplicato di [come creare l'effetto dell'icona di wobbling di iphone?] (Http://stackoverflow.com/questi ons/929364/how-to-create-iphones-wobbling-icon-effect) – kennytm

+0

Dai un'occhiata a questo: [Effetto Wobble] (https://github.com/rajendrahn/ShakeAnimation) – Raj

risposta

11

Ho provato a fare qualcosa del genere per un'app per iPad.

Ho provato a fare alcune rotazioni (con CAAnimation) alla vista. Ecco un esempio di codice che ho scritto:

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

}

e si dovrebbe cercare di applicare questo al vostro livello (con funzione di: addAnimation). Qui, la proprietà autorevers è quella di alternare l'orientamento sinistro e destro. Prova a impostare altri valori sull'angolo e sulla durata.

Ma nel mio caso ho dovuto aggiungere altri angoli al metodo CATransform3DMakeRotation, a seconda dell'orientamento primo strato ^^

Good Luck! Vincent

+1

Sei fantastico amico mio! !! – user446718

31

La risposta di Vinzius è molto bella. Tuttavia, l'oscillazione ruota solo da 0 radianti a 0,08. Quindi l'oscillazione può sembrare un po 'sbilanciata. Se si ottiene questo stesso problema quindi si consiglia di aggiungere sia un negativo e una rotazione positiva utilizzando un CAKeyframeAnimation piuttosto che 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;  
} 

È possibile utilizzare questo metodo di animazione per la visualizzazione o il pulsante mi piace questo.

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

Grande animazione, grazie. Prova entrambe le risposte, entrambe sono fantastiche questa è migliore per la mia opinione. – shannoga

+0

come aggiungerlo alla mia vista o pulsante ..? – g212gs

14

Guardando l'attuazione iOS un po 'più da vicino, ci sono due cose che fanno loro un po' più realistico rispetto al codice di cui qui:

  • Le icone sembrano avere un rimbalzo e un rotazione
  • Ogni icona ha la sua tempistica - non sono tutti sincronizzati

mi sulla base delle risposte qui (e con qualche aiuto da questo answer) per aggiungere la rotazione, il rimbalzo e un po 'di casualità alla durata di ogni animazione.

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

ho implementato questo codice su un UICollectionView che avevano 30 elementi rimbalzare e la performance è stata impeccabile su 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") 

Objective 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

Codice di paiego modificato per soddisfare le mie esigenze: feedback dell'animazione dell'errore visivo sull'azione dell'utente (toccare). Succede una volta - non è un costante dimenarsi come l'animazione di modifica delle animazioni delle app 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; 
} 

Usage:

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

Spero che questo aiuti qualcun altro.

2

risposta di Riscritta Sebastien a 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() 
    } 

Guardate questa iOS SpingBoard example