隐藏在NSStackView中的平滑子视图

时间:2019-08-24 05:14:23

标签: macos appkit nsstackview

我目前正在为Mac的菜单栏类型应用程序设计原型。我的早期代码基于本教程。

https://www.raywenderlich.com/450-menus-and-popovers-in-menu-bar-apps-for-macos

在其中,选择状态项时,他们使用NSPopover。我计划使用垂直NSStackView来显示和隐藏子视图。我使用Apple的InfoBarStackView作为NSStackView代码的起点。

与Apple代码不同,我希望能够更改NSPopover的大小以根据需要增大和缩小区域。

我有工作的代码,但是我发现底部表格视图的标题是“抖动的”,因为它被隐藏了。我以一个gif为例。注意,由于gif的“帧速率”,抖动很小。在现实中这很明显。从本质上讲,TABLEVIEW 1 NSTableView的高度似乎越来越小。我可以说它与窗口重新调整大小有关,而窗口重新调整大小与约束调整大小不同步。

我想知道是否有替代方法来处理此动画或使动画平滑化?

我还看到了其他SO发布信息,但是在代码中,作者使用的是NSPanel

Autolayout: NSStackView won't resize parent view when height dynamically changed

在该代码中(来自他的GitHub),NSPanel的绘图使用自定义drawRect代码在窗口顶部绘制箭头。另外,我计划允许分离NSPopover。这就是为什么我要研究NSPopoverNSPanel的原因,因为它为此需要更少的支持代码。但是,如果整体表现更好,我不反对转向NSPanel

下面列出了我用于调整NSPopover大小的代码。本质上,这是Apple代码,并带有更改窗口框架大小的附加功能。

    func animateDisclosure(disclose: Bool, animated: Bool) {
        if let viewController = self as? BaseViewController {
            if let constraint = viewController.heightConstraint {
                let heightValue = disclose ? viewController.savedDefaultHeight : 0
                if animated {
                    NSAnimationContext.runAnimationGroup({ (context) -> Void in
                        context.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.easeInEaseOut)
                        constraint.animator().constant = heightValue
                        if let app = NSApplication.shared.delegate as? AppDelegate {
                            if var frame = app.appController.popover.contentViewController?.view.window?.frame {
                                let change = disclose ? viewController.savedDefaultHeight : -viewController.savedDefaultHeight
                                frame.origin.y -= change
                                frame.size.height += change
                                app.appController.popover.contentViewController?.view.window?.animator().setFrame(frame, display: true)
                            }
                        }
                    }, completionHandler: { () -> Void in
                        // animation completed
                    })
                } else {
                    constraint.constant = heightValue
                }
            }
        }
    }

enter image description here

0 个答案:

没有答案