我是初学Cocoa开发人员。我被聘用的团队在Swift中进行OS X开发而不使用nib文件(显然主菜单除外)。所以,在我加入团队之前,我正在努力学习这一点。以下是我到目前为止的情况:
我创建了一个没有故事板的新OS X项目。我创建了一个名为MainWindowController.swift的新文件,使其成为NSWindowController的子类,并且没有创建xib / nib文件。我还使MainWindowController实现了NSWindowDelegate协议
在MainMenu.xib文件中,我默认删除了应用程序附带的窗口,但我保留了主菜单。
在app delegate中,我删除了窗口的默认插座。
然后我在app delegate中以编程方式创建了一个NSWindow。我希望MainWindowController成为这个窗口的委托。这就是我的AppDelegate的样子:
import Cocoa
@NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate {
let newWindow = NSWindow(contentRect: NSMakeRect(100, 100, NSScreen.mainScreen()!.frame.width/2, NSScreen.mainScreen()!.frame.height/2), styleMask: NSTitledWindowMask|NSResizableWindowMask|NSMiniaturizableWindowMask|NSClosableWindowMask, backing: NSBackingStoreType.Buffered, `defer`: false)
func applicationDidFinishLaunching(aNotification: NSNotification) {
// Insert code here to initialize your application
let wc = MainWindowController.init(window: newWindow)
wc.showWindow(self)
}
func applicationWillTerminate(aNotification: NSNotification) {
// Insert code here to tear down your application
}
}
正如您所看到的,我正在创建一个窗口对象,然后在applicationDidFinishLaunching方法中,我使用该窗口初始化我的自定义NSWindowController,然后显示该窗口。我不确定这是否正确。
然后,在我的自定义NSWindowController中,我正在制作自己的'窗口的代表使用' self.window?.delegate = self'。这就是我的MainWindowController的外观
import Cocoa
class MainWindowController: NSWindowController, NSWindowDelegate {
override func windowDidLoad() {
super.windowDidLoad()
self.window?.delegate = self
// Implement this method to handle any initialization after your window controller's window has been loaded from its nib file.
}
func windowDidMiniaturize(notification: NSNotification) {
print("Window minimized")
}
func windowWillClose(notification: NSNotification) {
print("Window closing")
}
}
如您所见,我在委托方法中有几个测试打印。
当我运行应用程序时,窗口会显示。但是,当我最小化或关闭窗口时,没有任何内容被打印到控制台。因此,似乎没有为窗口正确设置委托。
做事的正确方法是什么?
答案 0 :(得分:5)
在AppDelegate
课程中,您不想将窗口存储在属性中,而是要存储窗口控制器。你现在拥有它的方式,没有对窗口控制器的强引用,因此在applicationDidFinishLaunching
完成执行时会被销毁。窗口控制器将保持对其窗口的强引用,因此您不需要对窗口保持单独的强引用。我也会在applicationDidFinishLaunching
中设置窗口的委托 - 我不确定当你不使用笔尖时是否调用了windowDidLoad
。
我认为你的AppDelegate
课应该是这样的:
class AppDelegate: NSObject, NSApplicationDelegate {
let windowController = MainWindowController(
window: NSWindow(contentRect: NSMakeRect(100, 100, NSScreen.mainScreen()!.frame.width/2, NSScreen.mainScreen()!.frame.height/2),
styleMask: NSTitledWindowMask|NSResizableWindowMask|NSMiniaturizableWindowMask|NSClosableWindowMask,
backing: NSBackingStoreType.Buffered,
`defer`: false))
func applicationDidFinishLaunching(aNotification: NSNotification) {
// Insert code here to initialize your application
windowController.window?.delegate = windowController
windowController.showWindow(self)
}
}
答案 1 :(得分:0)
这是 Aaron 答案(Xcode 12.4., Swift 5.3.)的稍微更新和更清晰的版本:
RewriteRule