当我们在OSX中需要密码的程序中输入错误的密码时,窗口会震动我如何在我的程序中实现它?
答案 0 :(得分:13)
当用户输入错误密码时使用以下代码
static int numberOfShakes = 8;
static float durationOfShake = 0.5f;
static float vigourOfShake = 0.05f;
CGRect frame=[self.view.window 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;
[self.view.window setAnimations:[NSDictionary dictionaryWithObject: shakeAnimation forKey:@"frameOrigin"]];
[[self.view.window animator] setFrameOrigin:[self.view.window frame].origin];
答案 1 :(得分:4)
这是@ SajjadZare在Swift中的回答:
Swift 2.0:
let numberOfShakes:Int = 8
let durationOfShake:Float = 0.5
let vigourOfShake:Float = 0.05
let frame:CGRect = (self.view.window?.frame)!
let shakeAnimation = CAKeyframeAnimation()
let shakePath = CGPathCreateMutable()
CGPathMoveToPoint(shakePath, nil, NSMinX(frame), NSMinY(frame))
for _ in 1...numberOfShakes {
CGPathAddLineToPoint(shakePath, nil, NSMinX(frame) - frame.size.width * CGFloat(vigourOfShake), NSMinY(frame))
CGPathAddLineToPoint(shakePath, nil, NSMinX(frame) + frame.size.width * CGFloat(vigourOfShake), NSMinY(frame))
}
CGPathCloseSubpath(shakePath)
shakeAnimation.path = shakePath
shakeAnimation.duration = CFTimeInterval(durationOfShake)
self.view.window?.animations = ["frameOrigin":shakeAnimation]
self.view.window?.animator().setFrameOrigin(self.view.window!.frame.origin)
Swift 3.0:
let numberOfShakes:Int = 8
let durationOfShake:Float = 0.5
let vigourOfShake:Float = 0.05
let frame:CGRect = (self.view.window!.frame)
let shakeAnimation = CAKeyframeAnimation()
let shakePath = CGMutablePath()
shakePath.move(to: CGPoint(x: NSMinX(frame), y: NSMinY(frame)))
for _ in 1...numberOfShakes {
shakePath.addLine(to: CGPoint(x:NSMinX(frame) - frame.size.width * CGFloat(vigourOfShake), y: NSMinY(frame)))
shakePath.addLine(to: CGPoint(x:NSMinX(frame) + frame.size.width * CGFloat(vigourOfShake), y: NSMinY(frame)))
}
shakePath.closeSubpath()
shakeAnimation.path = shakePath
shakeAnimation.duration = CFTimeInterval(durationOfShake)
self.view.window?.animations = ["frameOrigin":shakeAnimation]
self.view.window?.animator().setFrameOrigin((self.view.window?.frame.origin)!)
答案 2 :(得分:2)
我为街区而疯狂。这是一个应该有效的块版本......
- (void)shakeView:(UIView *)view times:(NSInteger)times completion:(void (^)(BOOL finished))completion {
if (times <= 0) {
completion(YES);
} else {
UIViewAnimationOptions options = UIViewAnimationOptionBeginFromCurrentState;
[UIView animateWithDuration:0.1 delay: 0.0 options: options
animations:^{
view.frame = CGRectOffset(view.frame, 6.0, 0.0); // shake to
}
completion:^(BOOL finished){
[UIView animateWithDuration:0.1 delay: 0.0 options:options
animations:^{
view.frame = CGRectOffset(view.frame, -6.0, 0.0); // shake fro
}
completion:^(BOOL finished) {
[self shakeView:view times:times-1 completion:completion];
}];
}];
}
}
答案 3 :(得分:0)
这就是我这样做的方式:
-(void)shakeLayer:(CALayer*)layer{
int repeats = 4;
float time = 0.04;
float movement = 5;
for(int x = 0; x < repeats; x++){
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(x*(time*4) * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
CABasicAnimation *posAnimation = [CABasicAnimation animationWithKeyPath:@"transform.translation.x"];
[posAnimation setFromValue:[NSNumber numberWithFloat:0]];
[posAnimation setToValue:[NSNumber numberWithFloat:movement]];
[posAnimation setBeginTime:0.0];
[posAnimation setDuration:time];
CABasicAnimation *negAnimation = [CABasicAnimation animationWithKeyPath:@"transform.translation.x"];
[negAnimation setFromValue:[NSNumber numberWithFloat:movement]];
[negAnimation setToValue:[NSNumber numberWithFloat:-movement]];
[negAnimation setBeginTime:time];
[negAnimation setDuration:time*2];
CABasicAnimation *posAnimation2 = [CABasicAnimation animationWithKeyPath:@"transform.translation.x"];
[posAnimation2 setFromValue:[NSNumber numberWithFloat:-movement]];
[posAnimation2 setToValue:[NSNumber numberWithFloat:0]];
[posAnimation2 setBeginTime:time*3];
[posAnimation2 setDuration:time];
CAAnimationGroup *group = [CAAnimationGroup animation];
[group setDuration:time*4];
[group setAnimations:[NSArray arrayWithObjects:posAnimation, negAnimation, posAnimation2, nil]];
[layer addAnimation:group forKey:nil];
});
}
}