1

我正在使用无边框的 NSWindow 来创建一个滑出菜单,就像您在许多 IOS 应用程序中可能会发现的那样。我目前使用 setFrame:display:animate: 和两个预定义的矩形来创建滑动效果,并且我还有一个淡化主窗口背景的动画,当前在窗口完成动画后运行。

我非常想同时运行这两个动画。但是, 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"];
4

2 回答 2

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;
}];
于 2013-09-27T02:40:37.870 回答
0

以下对我有用(归功于这个答案)。由于明确,我认为这是一个更“正确”的解决方案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]; 
于 2015-09-15T06:42:38.733 回答