UIView shake animation

后端 未结 16 1237
梦毁少年i
梦毁少年i 2020-11-28 18:07

i\'m trying to make a UIView shake when a button is pressed.

I am adapting the code I found on http://www.cimgf.com/2008/02/27/core-animation-tutorial-window-shake-e

相关标签:
16条回答
  • 2020-11-28 18:54

    Here is a version using,

    + (void)animateKeyframesWithDuration:(NSTimeInterval)duration delay:(NSTimeInterval)delay options:(UIViewKeyframeAnimationOptions)options animations:(void (^)(void))animations completion:(void (^)(BOOL finished))completion
    

    Introduced in iOS 7.

        const CGFloat xDelta = 16.0f;
    
        [UIView animateKeyframesWithDuration:0.50f
                                       delay:0.0f
                                     options:UIViewKeyframeAnimationOptionCalculationModeLinear
                                  animations:^{
    
                                      [UIView addKeyframeWithRelativeStartTime:0.0
                                                              relativeDuration:(1.0/6.0)
                                                                    animations:^{
                                                                        self.passwordTextField.transform = self.usernameTextField.transform = CGAffineTransformMakeTranslation(xDelta, 0.0);
                                                                    }];
    
                                      [UIView addKeyframeWithRelativeStartTime:(1.0/6.0)
                                                              relativeDuration:(1.0/6.0)
                                                                    animations:^{
                                                                        self.passwordTextField.transform = self.usernameTextField.transform = CGAffineTransformMakeTranslation(-xDelta, 0.0);
                                                                    }];
    
                                      [UIView addKeyframeWithRelativeStartTime:(1.0/3.0)
                                                              relativeDuration:(1.0/3.0)
                                                                    animations:^{
                                                                        self.passwordTextField.transform = self.usernameTextField.transform = CGAffineTransformMakeTranslation(xDelta/2.0, 0.0);
                                                                    }];
    
                                      [UIView addKeyframeWithRelativeStartTime:(2.0/3.0)
                                                              relativeDuration:(1.0/3.0)
                                                                    animations:^{
                                                                        self.passwordTextField.transform = self.usernameTextField.transform = CGAffineTransformIdentity;
                                                                    }];
    
                                  }
                                  completion:NULL];
    
    0 讨论(0)
  • 2020-11-28 18:57

    I wrote that post. It's overkill for a UIView, plus the parameters are geared toward an OSX app. Do this instead.

    CABasicAnimation *animation = 
                             [CABasicAnimation animationWithKeyPath:@"position"];
    [animation setDuration:0.05];
    [animation setRepeatCount:8];
    [animation setAutoreverses:YES];
    [animation setFromValue:[NSValue valueWithCGPoint:
                   CGPointMake([lockView center].x - 20.0f, [lockView center].y)]];
    [animation setToValue:[NSValue valueWithCGPoint:
                   CGPointMake([lockView center].x + 20.0f, [lockView center].y)]];
    [[lockView layer] addAnimation:animation forKey:@"position"];
    

    You'll have to play with the duration and repeatCount parameters as well as the x distance from center in the from and to values, but it should give you what you need. I hope that helps. Let me know if you have any questions.

    ---


    Swift 3.0

    let midX = lockView.center.x
    let midY = lockView.center.y
    
    let animation = CABasicAnimation(keyPath: "position")
    animation.duration = 0.06
    animation.repeatCount = 4
    animation.autoreverses = true
    animation.fromValue = CGPoint(x: midX - 10, y: midY)
    animation.toValue = CGPoint(x: midX + 10, y: midY)
    layer.add(animation, forKey: "position")
    
    0 讨论(0)
  • 2020-11-28 18:59

    Swift 3 implementation based on @Mihael-Isaev answer

    private enum Axis: StringLiteralType {
        case x = "x"
        case y = "y"
    }
    
    extension UIView {
        private func shake(on axis: Axis) {
            let animation = CAKeyframeAnimation(keyPath: "transform.translation.\(axis.rawValue)")
            animation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionLinear)
            animation.duration = 0.6
            animation.values = [-20, 20, -20, 20, -10, 10, -5, 5, 0]
            layer.add(animation, forKey: "shake")
        }
        func shakeOnXAxis() {
            self.shake(on: .x)
        }
        func shakeOnYAxis() {
            self.shake(on: .y)
        }
    }
    
    0 讨论(0)
  • 2020-11-28 19:03

    @imike answer in Swift 4.2

    extension UIView {
    func shake() {
        let animation = CAKeyframeAnimation(keyPath: "transform.translation.x")
        animation.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.linear)
        animation.duration = 0.6
        animation.values = [-20, 20, -20, 20, -10, 10, -5, 5, 0]
        self.layer.add(animation, forKey: "shake")
    }}
    
    0 讨论(0)
提交回复
热议问题