我是swift和Xcode的新手:我正试图编写一个cocoa应用程序,似乎无法弄清楚如何完全隐藏我的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 -不确定这是否与它有关。如有任何建议或见解,我将不胜感激。
感谢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 )
}
}
}
Then in my Main。故事板,我选择文档大纲中的Window节点,并打开标识检查器(CMD + ALT + 3)。然后我在"自定义类"字段中指定我的"Window"类。