抖动动画效果

方法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 <QuartzCore/QuartzCore.h>

@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];
}




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值