7

我使用下面的代码来摇动视图并且它可以正常工作,现在我想摇动一个窗口我更改了两行,我用 code2 在代码中加粗但不起作用

//-------- 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];
4

4 回答 4

11

您需要添加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];

}
于 2014-05-06T10:05:30.143 回答
7

这是 NSWindow 扩展形式的 Swift 版本(基于 Anoop Vaidya 答案)。

可能的用法:

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

ETC...

扩展(Swift 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)
    }
}
于 2016-03-15T09:07:28.727 回答
2

斯威夫特 4 解决方案

    let window = self.view.window

    let numberOfShakes = 3
    let durationOfShake = 0.4
    let vigourOfShake : CGFloat = 0.03
    let frame : CGRect = (window?.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 * vigourOfShake, y:NSMinY(frame)))
        shakePath.addLine(to: CGPoint(x:NSMinX(frame) + frame.size.width * vigourOfShake, y:NSMinY(frame)))
    }

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

    let animations = [NSAnimatablePropertyKey(rawValue: "frameOrigin") : shakeAnimation]

    window?.animations = animations
    window?.animator().setFrameOrigin(NSPoint(x: frame.minX, y: frame.minY))
于 2018-05-10T07:16:13.777 回答
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)
    }

}
于 2016-12-22T13:50:55.823 回答