2012-05-09 2 views
4

私は以下のコードを使ってビューを動かし、正しく動作するようになったので、今度はウィンドウを振ってみたいと思います。動作しません。NSWindowにログイン失敗ウィンドウのようにNOと言って振る舞いを与える方法

//-------- code 1 
CGFloat DegreesToRadians(CGFloat degrees) 
{ 
    return degrees * M_PI/180; 
} 

NSNumber* DegreesToNumber(CGFloat degrees) 
{ 
    return [NSNumber numberWithFloat: 
      DegreesToRadians(degrees)]; 
} 
--------------- 
[self.view setWantsLayer:YES]; 

CAKeyframeAnimation * animation= [CAKeyframeAnimation animationWithKeyPath:@"transform.rotation.z"]; 
[animation setDuration:0.04]; 
[animation setRepeatCount:10]; 

srand([[NSDate date] timeIntervalSince1970]); 
float rand = (float)random(); 
[animation setBeginTime:CACurrentMediaTime() + rand * .0000000001]; 

NSMutableArray *values = [NSMutableArray array]; 
[values addObject:DegreesToNumber(-1)]; 
[values addObject:DegreesToNumber(1)]; 
[values addObject:DegreesToNumber(-1)];  
[animation setValues:values];   
[self.view.layer addAnimation:animation forKey:@"rotate"]; 


//-------- code 2 
[self.window.animator addAnimation:animation forKey:@"rotate"]; 
[self.window.animator setWantsLayer:YES]; 
+0

ルック[Core Animation Tutorial:Window Shake Effect](http://www.cimgf .com/2008/02/27/core-animation-tutorial-window-shake-effect /)を参照してください。私はそれがあなたにとって有益だと思います。ここでは、[Example project](http://www.cimgf.com/wp-content/uploads/2008/02/justsayno.zip)を直接ダウンロードすることができます。プロジェクトのウィンドウ:![Example image](http://i.stack.imgur.com/RNN5G.png) –

+0

CAKeyframeAnimationのトリックをありがとう。 作成されたパスは、アニメータがコピーを作成するため、アニメータに割り当てた後に解放する必要があります。 shakeAnimation.path = shakePath; CGPathRelease(shakePath); – berbie

答えて

8

QuartzCore Frameworkを追加する必要があります。

次に、以下を使用:ここ

#import <Quartz/Quartz.h> 


//below action calls the method `shakeWindow` 

- (IBAction)shake:(id)sender { 
    [self shakeWindow]; 
} 

-(void)shakeWindow{ 

    static int numberOfShakes = 3; 
    static float durationOfShake = 0.5f; 
    static float vigourOfShake = 0.05f; 

    CGRect frame=[self.window frame]; 
    CAKeyframeAnimation *shakeAnimation = [CAKeyframeAnimation animation]; 

    CGMutablePathRef shakePath = CGPathCreateMutable(); 
    CGPathMoveToPoint(shakePath, NULL, NSMinX(frame), NSMinY(frame)); 
    for (NSInteger 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.window setAnimations:[NSDictionary dictionaryWithObject: shakeAnimation forKey:@"frameOrigin"]]; 
    [[self.window animator] setFrameOrigin:[self.window frame].origin]; 

} 
5

は(アヌープVaidyaの回答に基づいて)NSWindowの延長の形でスウィフトバージョンです。

可能な用法:

window?.shakeWindow() 
view.window?.shakeWindow() 
NSApp.windows.first?.shakeWindow() 

等...

拡張(スウィフト3.0):

extension NSView { 

    func shake(with intensity : CGFloat = 0.05, duration : Double = 0.5){ 
     let numberOfShakes  = 3 
     let frame : CGRect = self.frame 
     let shakeAnimation :CAKeyframeAnimation = CAKeyframeAnimation() 

     let shakePath = CGMutablePath() 
     shakePath.move(to: CGPoint(x:NSMinX(frame),y:NSMinY(frame))) 

     for _ in 0...numberOfShakes-1 { 
      shakePath.addLine(to: CGPoint(x:NSMinX(frame) - frame.size.width * intensity,y:NSMinY(frame))) 
      shakePath.addLine(to: CGPoint(x:NSMinX(frame) + frame.size.width * intensity,y:NSMinY(frame))) 
     } 

     shakePath.closeSubpath() 
     shakeAnimation.path = shakePath 
     shakeAnimation.duration = duration 

     self.animations = ["frameOrigin":shakeAnimation] 
     self.animator().setFrameOrigin(self.frame.origin) 
    } 
} 
0

スウィフト3溶液:この素敵なチュートリアルで

extension NSWindow { 

    func shakeWindow(){ 
     let numberOfShakes  = 3 
     let durationOfShake  = 0.25 
     let vigourOfShake : CGFloat = 0.015 

     let frame : CGRect = self.frame 
     let shakeAnimation :CAKeyframeAnimation = CAKeyframeAnimation() 

     let shakePath = CGMutablePath() 
     shakePath.move(to: CGPoint(x: frame.minX, y: frame.minY)) 

     for _ in 0...numberOfShakes-1 { 
      shakePath.addLine(to: CGPoint(x: frame.minX - frame.size.width * vigourOfShake, y: frame.minY)) 
      shakePath.addLine(to: CGPoint(x: frame.minX + frame.size.width * vigourOfShake, y: frame.minY)) 
     } 

     shakePath.closeSubpath() 

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

     self.animations = ["frameOrigin":shakeAnimation] 
     self.animator().setFrameOrigin(self.frame.origin) 
    } 

} 
関連する問題