2010-09-13 95 views
30

我們目前正在開發包含一系列圖標的應用程序。我們希望圖標在按下時像應用刪除動畫一樣擺動。什麼是編碼這個動畫序列的最佳方式?如何創建類似於iphone刪除動畫的擺動動畫

+3

可能重複[如何創建iphone的搖擺圖標效果?](http://stackoverflow.com/questi ons/929364/how-to-create-iphones-wobbling-icon-effect) – kennytm 2010-09-13 20:09:58

+0

看看這個: [擺動效果](https://github.com/rajendrahn/ShakeAnimation) – Raj 2013-02-06 10:47:29

回答

11

我試圖爲iPad應用做類似的事情。

我試圖做一些旋轉(與CAAnimation)到視圖。這裏是我寫的示例代碼:

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

}

而你應該嘗試應用這一個到你的圖層(使用函數:addAnimation)。 這裏,autoreverses屬性是交替左右方向。 嘗試將其他值設置爲角度和持續時間。

但在我的情況下,我不得不給別人的角度添加到CATransform3DMakeRotation方法,根據初始層取向^^

祝您好運! Vincent

+1

你真棒我的朋友! ! – user446718 2010-09-13 23:00:08

31

Vinzius的答案非常酷。但擺動只從0弧度旋轉到0.08。因此擺動看起來有點不平衡。如果你得到同樣的問題,那麼你可能想通過使用CAKeyframeAnimation而非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;  
} 

您可以使用此方法的動畫爲您的視圖或按鈕這樣的。

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

偉大的動畫,謝謝。嘗試兩種答案,兩者都很好,這對我的意見更好。 – shannoga 2012-03-26 13:02:54

+0

如何將它添加到我的視圖或按鈕..? – g212gs 2014-07-05 04:59:08

14

望着iOS的實施有點接近,這裏有提到兩件事情,讓他們有點比代碼更現實:

  • 的圖標似乎有反彈以及一旋轉
  • 每個圖標都有自己的時間 - 他們是不是所有的同步

我自己基礎上的答案在這裏(以及與此一些幫助10)在每個動畫的持續時間中添加旋轉,反彈和一點隨機性。

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

我實現上的UICollectionView其中有30個項目彈跳此代碼並表現得完美無瑕在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") 

目標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

編輯paiego的代碼以滿足我的需求:用戶操作時的視覺錯誤動畫反饋(點擊)。它只發生過一次 - 它不是像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; 
} 

用法:

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

希望這可以幫助其他人。

2

重寫了塞巴斯蒂安在斯威夫特回答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() 
    } 

看這個的iOS SpingBoard example