如何创建类似于iphone删除动画的摆动动画

use*_*718 35 core-animation objective-c ios

我们目前正在开发一个包含一系列图标的应用程序.我们希望图标在按下时像应用程序删除动画一样摆动.编码这个动画序列的最佳方法是什么?

pai*_*ego 33

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;    
}
Run Code Online (Sandbox Code Playgroud)

您可以将此动画方法用于您的视图或按钮.

[self.yourbutton.layer addAnimation:[self getShakeAnimation] forKey:@""];
Run Code Online (Sandbox Code Playgroud)

  • 伟大的动画,谢谢.尝试这两个答案,两者都很好,这个对我的看法更好. (2认同)

Seb*_*tin 15

再看一下iOS实现,有两件事比他们提到的代码更真实:

  • 图标似乎具有反弹和旋转
  • 每个图标都有自己的时间 - 它们并非全部同步

我基于这里的答案(并在这个答案的帮助下)将旋转,弹跳和一些随机性添加到每个动画的持续时间.

#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;
}
Run Code Online (Sandbox Code Playgroud)

我在UICollectionView上实现了这个代码,它有30个项目弹跳,在iPad 2上表现完美无瑕.


Mit*_*iya 13

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")
Run Code Online (Sandbox Code Playgroud)

目标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;
}
Run Code Online (Sandbox Code Playgroud)


Vin*_*ius 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方法,具体取决于初始层方向^^

祝好运 !文森特


Vic*_*r96 6

在Swift 3中重写了Sebastien的答案.

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()
}
Run Code Online (Sandbox Code Playgroud)


Bes*_*rov 6

    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()
        }

    func randomInterval(_ interval: TimeInterval, variance: Double) -> TimeInterval {
        return interval + variance * Double((Double(arc4random_uniform(1000)) - 500.0) / 500.0)
    }
Run Code Online (Sandbox Code Playgroud)

看看这个 iOS SpingBoard示例

跳板