我目前正在为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
。这就是为什么我要研究NSPopover
与NSPanel
的原因,因为它为此需要更少的支持代码。但是,如果整体表现更好,我不反对转向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
}
}
}
}