xcode - 如何在 NSWindow 上只显示工具栏

标签 xcode swift cocoa nswindow nstoolbar

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

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

在我的 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 )
    }
}

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

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

最佳答案

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

最终对我有用的解决方案涉及当窗口内容被隐藏时临时删除对内容 View 的约束,然后当内容 View 变得可见时再次添加约束。作为引用(以防将来有人遇到这个问题),这是我所做的:

在我的 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)。然后我在“自定义类”字段中指定了我的“窗口”类。

关于xcode - 如何在 NSWindow 上只显示工具栏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31869265/

相关文章:

android - 由于缺少 info.plist 和其他文件,Worklight 在 OS X、iPhone 和 Android 上的构建失败

ios - UIButton选择状态并存储值

objective-c - NSInvocation 无参数

objective-c - pathForResource inDirectory 问题

xcode - 当新节点可见时,SceneKit 应用程序卡顿

swift - 创建符号断点/修复自动布局问题

ios - Xcode 8 swift 3 从 URL 加载图像并将其传递到 segue 目的地

swift - didOutputSampleBuffer 丢帧

swift - 如何存储选项

objective-c - Objective C 中的静默安装