[ios] UIView 흔들림 애니메이션

버튼을 눌렀을 때 UIView 흔들림을 만들려고합니다.

http://www.cimgf.com/2008/02/27/core-animation-tutorial-window-shake-effect/ 에서 찾은 코드를 수정하고 있습니다 .

그러나 다음 코드를 수정하여 UIView를 흔들면 작동하지 않습니다.

- (void)animate {
    const int numberOfShakes = 8;
    const float durationOfShake = 0.5f;
    const float vigourOfShake = 0.1f;

    CAKeyframeAnimation *shakeAnimation = [CAKeyframeAnimation animation];

    CGRect frame = lockView.frame;

    CGMutablePathRef shakePath = CGPathCreateMutable();
    CGPathMoveToPoint(shakePath, NULL, CGRectGetMinX(frame), CGRectGetMinY(frame));

    for (int index = 0; index < numberOfShakes; ++index) {
        CGPathAddLineToPoint(shakePath, NULL, CGRectGetMinX(frame) - frame.size.width * vigourOfShake, CGRectGetMinY(frame));

        CGPathAddLineToPoint(shakePath, NULL, CGRectGetMinX(frame) + frame.size.width * vigourOfShake, CGRectGetMinY(frame));
    }

    CGPathCloseSubpath(shakePath);

    shakeAnimation.path = shakePath;
    shakeAnimation.duration = durationOfShake;


    [lockView.layer addAnimation:shakeAnimation forKey:@"frameOrigin"];

}



답변

나는 그 포스트를 썼다. UIView에는 지나친 일이며 매개 변수는 OSX 앱에 맞춰져 있습니다. 대신 이것을하십시오.

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"];

duration 및 repeatCount 매개 변수뿐만 아니라 from 및 to 값의 중심으로부터 x 거리를 사용해야하지만 필요한 것을 제공해야합니다. 도움이 되었기를 바랍니다. 궁금한 점이 있으면 알려주세요.


스위프트 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")


답변

나는 틀린 암호 흔들림 애니메이션에 이상적인 멋진 동작을 가진이 솔루션을 선호합니다.

view.transform = CGAffineTransformMakeTranslation(20, 0);
[UIView animateWithDuration:0.4 delay:0.0 usingSpringWithDamping:0.2 initialSpringVelocity:1.0 options:UIViewAnimationOptionCurveEaseInOut animations:^{
    view.transform = CGAffineTransformIdentity;
} completion:nil];

스위프트 3

extension UIView {
    func shake() {
        self.transform = CGAffineTransform(translationX: 20, y: 0)
        UIView.animate(withDuration: 0.4, delay: 0, usingSpringWithDamping: 0.2, initialSpringVelocity: 1, options: .curveEaseInOut, animations: {
            self.transform = CGAffineTransform.identity
        }, completion: nil)
    }
}


답변

여기 내 멋지고 간단한 버전이 있습니다. 이것은 잘못된 로그인을 할 때 Mac OS X에서받는 흔들림을 시뮬레이션합니다. 원하는 경우 UIView의 카테고리로 추가 할 수 있습니다.

@implementation UIView (DUExtensions)

- (void) shake {
    CAKeyframeAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:@"transform.translation.x"];
    animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];
    animation.duration = 0.6;
    animation.values = @[ @(-20), @(20), @(-20), @(20), @(-10), @(10), @(-5), @(5), @(0) ];
    [self.layer addAnimation:animation forKey:@"shake"];
}

@end

애니메이션 값은 뷰 현재 위치에서 x 오프셋입니다. 뷰를 오른쪽으로 이동하는 양수 값과 왼쪽으로 음수 값을 이동합니다. 연속적으로 낮추면 자연스럽게 추진력을 잃는 흔들림이 생깁니다. 원하는 경우이 숫자를 조정할 수 있습니다.


답변

누구나 필요로하는 경우를 대비하여 확장 기능으로 빠른 버전이 있습니다.

extension UIImageView{
    func vibrate(){
        let animation = CABasicAnimation(keyPath: "position")
        animation.duration = 0.05
        animation.repeatCount = 5
        animation.autoreverses = true
        animation.fromValue = NSValue(CGPoint: CGPointMake(self.center.x - 2.0, self.center.y))
        animation.toValue = NSValue(CGPoint: CGPointMake(self.center.x + 2.0, self.center.y))
        self.layer.addAnimation(animation, forKey: "position")
    }
}

그러면 작은 UIImageView (약 15×15)에 애니메이션이 적용됩니다. 더 큰 것을 애니메이션화해야하는 경우 2.0 이동 계수를 더 큰 것으로 변경할 수 있습니다.


답변

@bandejapaisa 답변에 따라 Swift 3 용 UIView 확장

extension UIView {
    func shake() {
        let animation = CAKeyframeAnimation(keyPath: "transform.translation.x")
        animation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionLinear)
        animation.duration = 0.6
        animation.values = [-20, 20, -20, 20, -10, 10, -5, 5, 0]
        layer.addAnimation(animation, forKey: "shake")
    }
}


답변

다음 코드를 시도해 볼 수 있습니다.

아래 코드를 호출하려면 다음을 사용하십시오. [self earthquake:myObject];

#pragma mark EarthQuake Methods

- (void)earthquake:(UIView*)itemView
{
    AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);

    CGFloat t = 2.0;

    CGAffineTransform leftQuake  = CGAffineTransformTranslate(CGAffineTransformIdentity, t, -t);
    CGAffineTransform rightQuake = CGAffineTransformTranslate(CGAffineTransformIdentity, -t, t);

    itemView.transform = leftQuake;  // starting point

    [UIView beginAnimations:@"earthquake" context:itemView];
    [UIView setAnimationRepeatAutoreverses:YES]; // important
    [UIView setAnimationRepeatCount:3];
    [UIView setAnimationDuration:0.05];
    [UIView setAnimationDelegate:self];
    [UIView setAnimationDidStopSelector:@selector(earthquakeEnded:finished:context:)];

    itemView.transform = rightQuake; // end here & auto-reverse

    [UIView commitAnimations];
}

- (void)earthquakeEnded:(NSString *)animationID finished:(NSNumber *)finished context:(void *)context
{
    if ([finished boolValue])
    {
        UIView* item = (UIView *)context;
        item.transform = CGAffineTransformIdentity;
   }
}


답변

UIButton 클릭 이벤트에서이 메서드를 호출 할 수 있습니다.

-(void)shakescreen
{
    //Shake screen
    CGFloat t = 5.0;
    CGAffineTransform translateRight = CGAffineTransformTranslate(CGAffineTransformIdentity, t, t);
    CGAffineTransform translateLeft = CGAffineTransformTranslate(CGAffineTransformIdentity, -t, -t);

    self.view.transform = translateLeft;

    [UIView animateWithDuration:0.05 delay:0.0 options:UIViewAnimationOptionAutoreverse|UIViewAnimationOptionRepeat animations:^
    {
         [UIView setAnimationRepeatCount:2.0];
         self.view.transform = translateRight;
    } completion:^(BOOL finished)

      {
          if (finished)
          {
             [UIView animateWithDuration:0.05 delay:0.0 options:UIViewAnimationOptionBeginFromCurrentState animations:^
          {
              self.view.transform = CGAffineTransformIdentity;
          }
          completion:NULL];
      }
  }];
}

이것이 당신을 도울 것입니다 🙂