NSWindow翻转动画 - 像iWork一样

4

我正在尝试实现类似于iWork中的窗口翻转功能 -

https://dl.dropbox.com/u/2338382/Window%20Flipping.mov

然而,我似乎找不到一个简单明了的方法来实现这一点。一些教程建议将窗口两侧的快照图像粘贴到一个更大的透明窗口中并对其进行动画处理。这可能有效,但似乎有些hacky,而且示例代码总是臃肿的。一些教程建议使用私有API,由于该应用程序可能会绑定MAS,我想避免使用私有API。

如何实现这一点?有人有任何提示吗?

NSWindow+Flipping

我已经将下面链接的古老代码重写为NSWindow+Flipping。您可以从我的杂项Cocoa收藏GitHub上的PCSnippets获取这些源文件。


在这里查看:http://stackoverflow.com/questions/24567190/nswindow-flip-animation-easy-and-universal/24567191#24567191 - Oleg Uryutin
1个回答

4
您可以使用 CoreGraphics 框架 来实现这一点。看一下这个例子:
- (void) flipWithDuration: (float) duration forwards: (BOOL) forwards
{
  CGSTransitionSpec spec;
  CGSTransitionHandle transitionHandle;
  CGSConnection cid = CGSDefaultConnection;

  spec.type = CGSFlip;
  spec.option = 0x80 | (forwards ? 2 : 1);
  spec.wid = [self windowNumber];
  spec.backColor = nil;

  transitionHandle = -1;
  CGSNewTransition (cid, &spec, &transitionHandle);
  CGSInvokeTransition (cid, transitionHandle, duration);
  [[NSRunLoop currentRunLoop] runUntilDate: 
        [NSDate dateWithTimeIntervalSinceNow: duration]];
  CGSReleaseTransition (cid, transitionHandle);
}

你可以下载示例项目:这里。更多信息请参考这里更新: 看看这个项目。那正是你需要的。

关于该项目:

这个类别中的NSWindow允许您使用Dashboard小部件流行的"flip"动画切换一个窗口和另一个窗口。这是一个很好的借口来了解一些关于CoreImage以及如何在Cocoa中使用它的知识。演示应用程序展示了如何使用它。滚动到末尾查看此版本的新功能!

基本上,你所需要做的就是像这样做:

[someWindow flipToShowWindow:someOtherWindow forward:YES];

然而,这段代码有一些假设条件:—someWindow(初始窗口)已经在屏幕上可见。—someOtherWindow(最终窗口)还没有在屏幕上可见。—两个窗口可以调整为相同的大小,且不太大或复杂——后者的条件在您的CPU/视频卡速度越快时越不重要。—当动画正在运行时,窗口不会消失。—用户在动画运行时不会尝试单击动画窗口或执行其他操作。
实现非常简单。我将最终位置和大小移动到与初始窗口相同的位置。然后,我定位一个较大的透明窗口,以覆盖该框架。我将两个窗口内容呈现为CIImages,隐藏两个窗口,并开始动画。动画的每个帧将透视扭曲的图像渲染到透明窗口中。当动画完成时,我显示最终窗口。使用一些技巧可以使此过程更快;翻转窗口仅设置一次;最终窗口通过将其alpha设置为0.0来隐藏,而不是将其排序并稍后再次排序。
主要瓶颈是CoreImage筛选器,第一帧始终需要更长时间才能渲染-比剩余帧所需的时间长4或6倍。我想这段时间用于设置和下载到视频卡。因此,我计算了这需要多长时间,并在旋转开始显示的阶段绘制了第二个帧。动画从这一点开始,但如果前两个框架花费太长时间,则会延长持续时间,以确保至少还有5个框架将被渲染。这将发生在硬件慢或窗口大的情况下。最后,我根本不会渲染最后一帧,并交换最终窗口。

我不能100%确定这不是使用私有API,但我认为不是。嗯...是的,这有点bug。 - Justin Boo
是的...即使我可以使用潜在的私有API调用,我也不能发布这样视觉上存在缺陷的东西。如果你找到了一种方法来稍微清理一下它,请发帖!这是迄今为止最有前途的线索。 - Patrick Perini
任何以“CGS”为前缀的CoreGraphics API都是私有API。只有以“CG”为前缀的API是公共API。 - kperryua
@JustinBoo 当我将NSWindow_Flipr直接拖入我的项目中时,窗口翻转的速度非常慢,并且在完成后永远消失了。有什么想法吗? - Patrick Perini
@pcperini 我创建了一个新项目并测试它,所以它运行良好。当你遇到“永久消失”的问题时,你可能是做错了什么。为了进行滞后测试,我在每个窗口中添加了两个大图像,但仍然可以正常工作。(翻转速度可以在这里更改:#define DURATION (0.75))。因此,如果您的窗口翻转有延迟-这取决于您的项目中有什么。这是我创建的测试项目: http://www63.zippyshare.com/v/85211094/file.html。 - Justin Boo
显示剩余8条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接