multithreading - NSSplitViewItem 折叠动画和窗口 setFrame 冲突

标签 multithreading core-animation swift nssplitview

我正在尝试使(10.10 中的新功能)NSSplitViewItem 折叠和展开,同时移动它的包含窗口,以便将整个东西保持在“原位”。

问题是我在动画中出现抽搐(如 here 所示)。

我进行折叠的代码是这样的:

func togglePanel(panelID: Int) {

     if let splitViewItem = self.splitViewItems[panelID] as? NSSplitViewItem {

          // Toggle the collapsed state
          NSAnimationContext.runAnimationGroup({ context in

               // special case for the left panel
               if panelID == 0 {
                    var windowFrame = self.view.window.frame
                    let panelWidth = splitViewItem.viewController.view.frame.width
                    if splitViewItem.collapsed {
                         windowFrame.origin.x -= panelWidth
                         windowFrame.size.width += panelWidth
                    } else {
                         windowFrame.origin.x += panelWidth
                         windowFrame.size.width -= panelWidth
                    }
                    self.view.window.animator().setFrame(windowFrame, display: true)
               }
               splitViewItem.animator().collapsed = !splitViewItem.collapsed
          }, completionHandler: nil)
     }
}

我知道“不要跨流”问题(来自 WWDC'13 session 213),其中在主线程上运行的窗口大小调整动画和在单独线程上运行的核心动画折叠动画会干扰每个其他。将 splitViewItem 折叠动画放到主线程上似乎是错误的方法,我有一种挥之不去的感觉,我缺少一种更好的方法。

由于我在任何地方(还)找不到任何关于 NSSplitViewItems 的文档,我将不胜感激对此的任何见解。

我在 GitHub 上有一个小测试项目 here如果有人想看的话。

更新 提到的项目现已更新为解决方案。

谢谢, 特奥

最佳答案

该问题类似于“不要交叉流”问题,因为您创建的动画有两个驱动程序:(1) Split View项 (2) 窗口,它们不是同步。

在 '13 Cocoa Animations 演讲的示例中,设置了约束以产生正确的窗口内动画,因为只有窗口的框架是动画的。

类似的东西可以在这里尝试——只动画窗口的框架而不是分割 View 项目,但由于项目管理用于(取消)折叠的约束,应用程序无法控制窗口内内容的动画方式:

Animating Window frame

相反, Split View项动画可以完全驱动动画并使用 NSWindow 的 -anchorAttributeForOrientation: 来描述窗口的框架如何受到影响。

if let splitViewItem = self.splitViewItems[panelID] as? NSSplitViewItem {
    let window = self.view.window
    if panelID == 0 {
        // The Trailing edge of the window is "anchored", alternatively it could be the Right edge
        window.setAnchorAttribute(.Trailing, forOrientation:.Horizontal)
    }
    splitViewItem.animator().collapsed = !splitViewItem.collapsed
}

Animating SplitViewItem

关于multithreading - NSSplitViewItem 折叠动画和窗口 setFrame 冲突,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24585247/

相关文章:

swift - 从 uiAlertController 中的文本字段检索内容

java - 通知不起作用..永远等待线程 Java

java - danceTo 方法行为的真实示例

ios - UIView appereance 从下到上,反之亦然(核心动画)

ios - CABasicAnimationanimationDidStart确实被调用,但animationDidStop从未被调用

ios - Action Extension,在 Instant Markup 中获取图像返回空白屏幕

swift - 如何在 Storyboard 的 Touch Bar 中添加 ScrollView ?

c# - 任务 MaxDegreeOfParallelism 每次都可以从我的列表中获取第一个 n 对象吗?

java - 为什么并发 HashMap 在由两个线程访问时可以正常工作,一个线程使用clear(),另一个线程使用putifAbsent()方法?

ios - 为什么这个 UIImageView 动画会泄漏?