ios抖动动画效果

方法1

-(void)earthquake:(UIView*)itemView
{
    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:5];
    [UIView setAnimationDuration:0.07];
    [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;
    }

}




方法2

-(void)shakeView:(UIView*)viewToShake
{
    CGFloat t =2.0;
    CGAffineTransform translateRight  =CGAffineTransformTranslate(CGAffineTransformIdentity, t,0.0);
    CGAffineTransform translateLeft =CGAffineTransformTranslate(CGAffineTransformIdentity,-t,0.0);

    viewToShake.transform = translateLeft;

    [UIView animateWithDuration:0.07 delay:0.0 options:UIViewAnimationOptionAutoreverse|UIViewAnimationOptionRepeat animations:^{
        [UIView setAnimationRepeatCount:2.0];
        viewToShake.transform = translateRight;
    } completion:^(BOOL finished){
        if(finished){
            [UIView animateWithDuration:0.05 delay:0.0 options:UIViewAnimationOptionBeginFromCurrentState animations:^{
                viewToShake.transform =CGAffineTransformIdentity;
            } completion:NULL];
        }
    }];

}

 


 

question:

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.

So I'd like for it to graphically shake my login view when the user enters the wrong user ID and password like the Mac login screen does.

Anyone know if there's a way to pull this off, or have any suggestions for another effect I could use?

 

answer:

1.

Simply changing the X coordinate of the center property of your view might do the trick. If you haven't done any core animation before it's pretty straight-forward.

First, start an animation right, then listen for it to finish, and then move back to the left, and so on. Getting the timing down so it "feels right" might take a while.

复制代码
- (void)animationFinishCallback:(NSString *)animationID finished:(BOOL)finished context:(void *)context
{
  if ([animationID isEqualToString:@"MoveRight"]) {
    [UIView beginAnimations:@"MoveLeft" context:NULL];
    [UIView setAnimationDuration:1.0];
    [UIView setAnimationDelay: UIViewAnimationCurveEaseIn];
    [UIView setAnimationDelegate:self];
    [UIView setAnimationDidStopSelector:@selector(animationFinishCallback:finished:context:)];

    myView.center = CGRectMake(newX, newY);
    [UIView commitAnimations];
  }
}
复制代码


2.I had seen some wobble animation and changed it to shake a view t pixels upright and downleft:

复制代码
- (void)earthquake:(UIView*)itemView
{
    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:5];
    [UIView setAnimationDuration:0.07];
    [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;
    }
}
复制代码

3.Using iOS 4+ block based UIKit animations (and loosely based on on jayccrown's answer):

复制代码
- (void)shakeView:(UIView *)viewToShake
{
    CGFloat t = 2.0;
    CGAffineTransform translateRight  = CGAffineTransformTranslate(CGAffineTransformIdentity, t, 0.0);
    CGAffineTransform translateLeft = CGAffineTransformTranslate(CGAffineTransformIdentity, -t, 0.0);

    viewToShake.transform = translateLeft;

    [UIView animateWithDuration:0.07 delay:0.0 options:UIViewAnimationOptionAutoreverse|UIViewAnimationOptionRepeat animations:^{
        [UIView setAnimationRepeatCount:2.0];
        viewToShake.transform = translateRight;
    } completion:^(BOOL finished) {
        if (finished) {
            [UIView animateWithDuration:0.05 delay:0.0 options:UIViewAnimationOptionBeginFromCurrentState animations:^{
                viewToShake.transform = CGAffineTransformIdentity;
            } completion:NULL];
        }
    }];
}
复制代码

4.QuartzCore

复制代码
#import "UIView+I7ShakeAnimation.h"
#import 

@implementation UIView (I7ShakeAnimation)  category模式

- (void)shakeX {
    [self shakeXWithOffset:40.0 breakFactor:0.85 duration:1.5 maxShakes:30];
}

- (void)shakeXWithOffset:(CGFloat)aOffset breakFactor:(CGFloat)aBreakFactor duration:(CGFloat)aDuration maxShakes:(NSInteger)maxShakes {
    CAKeyframeAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:@"position"];
    [animation setDuration:aDuration];
    
    
    NSMutableArray *keys = [NSMutableArray arrayWithCapacity:20];
    int infinitySec = maxShakes;
    while(aOffset > 0.01) {
        [keys addObject:[NSValue valueWithCGPoint:CGPointMake(self.center.x - aOffset, self.center.y)]];
        aOffset *= aBreakFactor;
        [keys addObject:[NSValue valueWithCGPoint:CGPointMake(self.center.x + aOffset, self.center.y)]];
        aOffset *= aBreakFactor;
        infinitySec--;
        if(infinitySec <= 0) {
            break;
        }
    }
    
    animation.values = keys;
    
    
    [self.layer addAnimation:animation forKey:@"position"];
}

@end
复制代码

 

复制代码
#import "AView.h"
#import "UIView+I7ShakeAnimation.h"

@implementation AView

- (void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    [self shakeX];
}

@end
复制代码
复制代码
#import "ExampleViewController.h"
#import "AView.h"
#import "UIView+I7ShakeAnimation.h"

@implementation ExampleViewController
- (void)viewDidLoad {
    [super viewDidLoad];
    
    AView *aView = [[AView alloc] initWithImage:[UIImage imageNamed:@"logo.png"]];
    aView.frame = CGRectMake(122,170,75,75);
    aView.userInteractionEnabled = YES;
    [self.view addSubview:aView];
    
    [aView shakeX];
    [aView release];
}
复制代码



5.同4,变种

复制代码
CAKeyframeAnimation * anim = [ CAKeyframeAnimation animationWithKeyPath:@"transform" ] ;
    anim.values = [ NSArray arrayWithObjects:
               [ NSValue valueWithCATransform3D:CATransform3DMakeTranslation(-5.0f, 0.0f, 0.0f) ],
               [ NSValue valueWithCATransform3D:CATransform3DMakeTranslation(5.0f, 0.0f, 0.0f) ], 
               nil ] ;
anim.autoreverses = YES ;
anim.repeatCount = 2.0f ;
anim.duration = 0.07f ;

[ viewToShake.layer addAnimation:anim forKey:@"nil" ] ;
复制代码



 

6.mac开发

CORE ANIMATION TUTORIAL: WINDOW SHAKE EFFECT

复制代码
- (CAKeyframeAnimation *)shakeAnimation:(NSRect)frame
{
    CAKeyframeAnimation *shakeAnimation = [CAKeyframeAnimation animation];
 
    CGMutablePathRef shakePath = CGPathCreateMutable();
    CGPathMoveToPoint(shakePath, NULL, NSMinX(frame), NSMinY(frame));
    int index;
    for (index = 0; index < numberOfShakes; ++index)
    {
        CGPathAddLineToPoint(shakePath, NULL, NSMinX(frame) - frame.size.width * vigourOfShake, NSMinY(frame));
        CGPathAddLineToPoint(shakePath, NULL, NSMinX(frame) + frame.size.width * vigourOfShake, NSMinY(frame));
    }
    CGPathCloseSubpath(shakePath);
    shakeAnimation.path = shakePath;
    shakeAnimation.duration = durationOfShake;
    return shakeAnimation;
}
复制代码


64位:

复制代码
static int numberOfShakes = 4;
static float durationOfShake = 0.1f;
static float vigourOfShake = 0.02f;
 
-(void)shakeWindow:(NSWindow *)window {
  NSRect frame = [window frame];
  CAKeyframeAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:@"frame"];
 
NSRect rect1 = NSMakeRect(NSMinX(frame) - frame.size.width * vigourOfShake, NSMinY(frame), frame.size.width, frame.size.height);
  NSRect rect2 = NSMakeRect(NSMinX(frame) + frame.size.width * vigourOfShake, NSMinY(frame), frame.size.width, frame.size.height);
  NSArray *arr = [NSArray arrayWithObjects:[NSValue valueWithRect:rect1], [NSValue valueWithRect:rect2], nil];
  [animation setValues:arr];
 
[animation setDuration:durationOfShake];
  [animation setRepeatCount:numberOfShakes];
 
[window setAnimations:[NSDictionary dictionaryWithObject:animation forKey:@"frame"]];
  [[window animator] setFrame:frame display:NO];
}

你可能感兴趣的:(IOS)