如何在NSWindow上仅显示工具栏

时间:2015-08-07 03:32:38

标签: xcode swift cocoa nswindow nstoolbar

我是swift和Xcode的新手:我正在尝试编写一个可可应用程序,似乎无法弄清楚如何完全隐藏NSWindow的内容。我在Xcode版本6.3.2上使用Swift;使用故事板设计的UI。

背景:我正在设计一个应用程序,在窗口工具栏中向用户显示一些控件。其中一个控件是用于切换内容的公开按钮:单击按钮允许用户展开工具栏下方的窗口内容以查看包含其他详细信息的一些视图。再次单击显示按钮会折叠窗口内容,隐藏窗口中包含的视图并再次仅显示工具栏。当应用程序加载时,只应显示工具栏 - 所有窗口内容都应隐藏,因为它们在此时无关紧要。

在我的WindowController.swift中,我有:

class WindowController: NSWindowController, NSToolbarDelegate {

override func windowDidLoad() {
    super.windowDidLoad()

    window?.hideContents()
}

我已定义了NSWindow扩展名;在NSWindow.swift我有:

private let TOOLBAR_WIDTH:CGFloat = 350.0
private let TOOLBAR_HEIGHT:CGFloat = 75.0
private let CONTENT_WIDTH:CGFloat = 800.0
private let CONTENT_HEIGHT:CGFloat = 600.0

public extension NSWindow {

    private var screenHeight : CGFloat {
       get {
           return NSScreen.mainScreen()!.frame.height
       }
    }

    public func hideContents() {
        let view = contentView as! NSView
        view.hidden = true
        view.needsDisplay = true

        collapseContentsFrame()
    }

    private func collapseContentsFrame() {

        var newFrame = NSRect(x:frame.origin.x, y:screenHeight, width: TOOLBAR_WIDTH, height: TOOLBAR_HEIGHT )

        setFrame( newFrame, display: false, animate: false )
    }

    public func showContents() {
        let view = contentView as! NSView
        view.hidden = false
        view.needsDisplay = true

        expandContentsFrame()
    }

    private func expandContentsFrame() {

        var newFrame = NSRect(x: frame.origin.x, y: screenHeight, width: CONTENT_WIDTH, height: CONTENT_HEIGHT )

        setFrame( newFrame, display: true, animate: false )
    }
}

这种工作方式:它隐藏了窗口中包含的视图的内容,并将框架缩小到与工具栏相同的大小。但是,工具栏下方仍然显示一个宽的空矩形 - 看起来窗口的框架没有正确调整大小(由于我没有权限,因此无法发布图像) 。我试过调整新框架上的值,但我似乎无法消除工具栏下方显示的额外空间。

在故事板中,窗口内容链接到TabViewController - 不确定这是否与它有关。任何建议/见解将不胜感激。

1 个答案:

答案 0 :(得分:0)

感谢Max和Lucas的建议。我尝试删除内容视图,在我的WindowController中保留对它的引用,然后在窗口展开时再将它添加回窗口。虽然这解决了手头的问题,但它为我创造了新问题:我以编程方式从工具栏调用segue,但如果窗口没有内容视图,则此segue调用崩溃。

最终为我工作的解决方案涉及在隐藏窗口内容时临时删除内容视图上的约束,然后在内容视图变为可见时再次添加约束。供参考(以防其他人将来遇到此问题),这就是我所做的:

在我的WindowController.swift中:

class WindowController: NSWindowController, NSToolbarDelegate {

    var mainWindow:Window {
        get {
            return window! as! Window
        }
    }

    override func windowDidLoad() {

        super.windowDidLoad()

        mainWindow.hideContents()
    }
}

在自定义的NSWindow子类中:

import Cocoa

class Window : NSWindow {

    private let TOOLBAR_WIDTH:CGFloat = 350.0
    private let TOOLBAR_HEIGHT:CGFloat = 75.0
    private let CONTENT_WIDTH:CGFloat = 800.0
    private let CONTENT_HEIGHT:CGFloat = 600.0

    private var constraints:[NSLayoutConstraint] = [NSLayoutConstraint]()

    override init( contentRect: NSRect,
        styleMask windowStyle: Int,
        backing bufferingType: NSBackingStoreType,
        defer deferCreation: Bool) {

        super.init( contentRect: contentRect, styleMask: windowStyle, backing: bufferingType, defer: deferCreation )
    }

    required init?( coder: NSCoder ) {
        super.init( coder: coder )
    }

    private var screenHeight : CGFloat {
        get {
            return NSScreen.mainScreen()!.frame.height
        }
    }

    private var view : NSView {
        get {
            return contentView as! NSView
        }
    }

    func hideContents() {

        view.hidden = true

        collapseContentsFrame()

        removeConstraints()
    }

    private func collapseContentsFrame() {
        var newFrame = NSRect(x:frame.origin.x, y:screenHeight, width: TOOLBAR_WIDTH, height: TOOLBAR_HEIGHT )
        setFrame( newFrame, display: false, animate: false )
    }

    private func removeConstraints() {
        constraints = view.constraints as! [NSLayoutConstraint]
        for constraint in constraints {
            view.removeConstraint( constraint )
        }
    }

    func showContents() {

        view.hidden = false

        expandContentsFrame()

        addConstraints()
    }

    private func expandContentsFrame() {
        var newFrame = NSRect(x: frame.origin.x, y: screenHeight, width: CONTENT_WIDTH, height: CONTENT_HEIGHT )
        setFrame( newFrame, display: true, animate: false )
    }

    private func addConstraints() {
        for constraint in constraints {
            view.addConstraint( constraint )
        }
    }
}

然后在我的Main.storyboard中,我选择文档大纲中的Window节点并调出身份检查器(CMD + ALT + 3)。然后我指定了我的" Window" " Custom Class"字段。