NSWindow的setFrame:display:animate:与其他动画同时运行

时间:2013-09-26 06:41:45

标签: nswindow nsanimation

我正在使用无边界的NSWindow来创建一个滑出菜单,就像许多IOS应用程序中所见。我目前使用setFrame:display:animate:有两个预定义的rects来创建滑动效果,我还有一个动画,它会淡化主窗口的背景,当前窗口完成动画后,它会运行

我非常希望同时运行这两种动画 。但是,setFrame:display:animate似乎会阻止所有其他代码,直到它完成。

有没有办法覆盖setFrame的这个功能:display:animate? 或者任何人都可以推荐一个解决方法吗?

我有运行[[self animator] setFrame:display:]的工作方法,但我更喜欢使用setFrame:display:animate,因为它在我当前的代码中很有特色,并且很容易配置持续时间。

一些代码:

//Currently used to animate the window
-(void)showPopWindow{
    [self selectAnimationTimeFor:NCpOpen];    
    [self setFrame:_initialRect display:YES];
    [self makeKeyAndOrderFront:NSApp];
    [self setFrame:_finalRect display:YES animate:YES];
}

这是我的另一个动画,当前在setFrame完成后运行(注意这在NSView的图层上运行)。

//...
[layer setBackgroundColor:CGColorCreateGenericRGB(0, 0, 0, 0.5)];

CABasicAnimation *fadeInBackground = [CABasicAnimation animationWithKeyPath:@"opacity"];
fadeBackground.duration = [self openAnimationResizeTime];
fadeBackground.fromValue = [NSNumber numberWithFloat:0.0f];
fadeBackground.toValue = [NSNumber numberWithFloat:1.0f];

[layer addAnimation:fadeInBackground forKey:@"opacity"];

2 个答案:

答案 0 :(得分:3)

使用NSAnimationContext和[[self animator] setAlphaValue:]解决问题,让我运行同步动画,然后在完成时执行一个块。

文档:

https://developer.apple.com/library/mac/documentation/Cocoa/Reference/NSAnimationContext_class/Introduction/Introduction.html#//apple_ref/occ/clm/NSAnimationContext/runAnimationGroup:completionHandler

工作代码:

// To avoid a strong reference cycle to self in block
__weak typeof(self)weakSelf = self;

[NSAnimationContext runAnimationGroup:^(NSAnimationContext *context) {
    [context setDuration: myDuration];
    [[weakSelf animator] setFrame:_initialRect display:YES];

    // ... other animations

} completionHandler:^{
    NSLog(@"done");
    [[weakSelf overCastView] removeFromSuperview];
    weakSelf.overCastView = nil;
}];

答案 1 :(得分:0)

以下为我工作(归功于this answer)。由于明确的NSAnimationNonblocking

,我认为这是一个更“正确”的解决方案
NSRect myNewFrame = NSMakeRect(0, 0, 123, 456);

NSDictionary* windowResize = [NSDictionary dictionaryWithObjectsAndKeys: window, NSViewAnimationTargetKey, [NSValue valueWithRect: myNewFrame], NSViewAnimationEndFrameKey, nil];
NSArray* animations = [NSArray arrayWithObjects:windowResize, nil];
NSViewAnimation* animation = [[NSViewAnimation alloc] initWithViewAnimations: animations];

[animation setAnimationBlockingMode: NSAnimationNonblocking];
[animation setAnimationCurve: NSAnimationEaseIn];
[animation setDuration: 0.4];     
[animation startAnimation];