Shake visual effect on iPhone (NOT shaking the device)

后端 未结 11 794
忘了有多久
忘了有多久 2020-12-02 05:06

On login failure, I\'d prefer to avoid showing an alert, it\'s too fleeting. Showing the alert and then showing the text somewhere on the login screen seems like duplication

11条回答
  •  一整个雨季
    2020-12-02 05:43

    This UIView category snippet worked for me. It's using 3 CABasingAnimations applied to view's layer.

    #import 
    #import 
    
    #define Y_OFFSET 2.0f
    #define X_OFFSET 2.0f
    #define ANGLE_OFFSET (M_PI_4*0.1f)
    
    @interface UIView (shakeAnimation)
    
    -(BOOL)isShakeAnimationRunning;
    -(void)startShakeAnimation;
    -(void)stopShakeAnimation;
    
    @end
    
    
    
    @implementation UIView (shakeAnimation)
    
    -(BOOL)isShakeAnimationRunning{
         return [self.layer animationForKey:@"shake_rotation"] != nil;
    }
    
    -(void)startShakeAnimation{
        CFTimeInterval offset=(double)arc4random()/(double)RAND_MAX;
        self.transform=CGAffineTransformRotate(self.transform, -ANGLE_OFFSET*0.5);
        self.transform=CGAffineTransformTranslate(self.transform, -X_OFFSET*0.5f, -Y_OFFSET*0.5f);
    
        CABasicAnimation *tAnim=[CABasicAnimation animationWithKeyPath:@"position.x"];
        tAnim.repeatCount=HUGE_VALF;
        tAnim.byValue=[NSNumber numberWithFloat:X_OFFSET];
        tAnim.duration=0.07f;
        tAnim.autoreverses=YES;
        tAnim.timeOffset=offset;
        [self.layer addAnimation:tAnim forKey:@"shake_translation_x"];
    
        CABasicAnimation *tyAnim=[CABasicAnimation animationWithKeyPath:@"position.y"];
        tyAnim.repeatCount=HUGE_VALF;
        tyAnim.byValue=[NSNumber numberWithFloat:Y_OFFSET];
        tyAnim.duration=0.06f;
        tyAnim.autoreverses=YES;
        tyAnim.timeOffset=offset;
        [self.layer addAnimation:tyAnim forKey:@"shake_translation_y"];
    
        CABasicAnimation *rAnim=[CABasicAnimation animationWithKeyPath:@"transform.rotation"];
        rAnim.repeatCount=HUGE_VALF;
        rAnim.byValue=[NSNumber numberWithFloat:ANGLE_OFFSET];
        rAnim.duration=0.15f;
        rAnim.autoreverses=YES;
        rAnim.timeOffset=offset;
        [self.layer addAnimation:rAnim forKey:@"shake_rotation"];
    }
    -(void)stopShakeAnimation{
        [self.layer removeAnimationForKey:@"shake_translation_x"];
        [self.layer removeAnimationForKey:@"shake_translation_y"];
        [self.layer removeAnimationForKey:@"shake_rotation"];
        [UIView animateWithDuration:0.2f animations:^{
            self.transform=CGAffineTransformRotate(self.transform, ANGLE_OFFSET*0.5);
            self.transform=CGAffineTransformTranslate(self.transform, X_OFFSET*0.5, Y_OFFSET*0.5f);
        }];
    }
    
    @end
    

    Hope it helpes someone :)

提交回复
热议问题