这就是我所拥有的:
NSWindow子类
import Cocoa import CoreLocation class TweetWindow: NSWindow { var locationManager: CLLocationManager! var geoCoder: CLGeocoder! @IBAction func tweetButtonPressed(sender:NSButton) { } func initialize() { self.titleVisibility = NSWindowTitleVisibility.Hidden; self.locationManager = CLLocationManager(); self.locationManager.desiredAccuracy = kCLLocationAccuracyBestForNavigation; self.locationManager.distanceFilter = 10; self.geoCoder = CLGeocoder(); } func windowWillShow() { if !self.visible { let systemAppearanceName = (NSUserDefaults.standardUserDefaults().stringForKey("AppleInterfaceStyle") ?? "Light").lowercaseString; let systemAppearance = systemAppearanceName == "dark" ? NSAppearance(named: NSAppearanceNameVibrantDark) : NSAppearance(named: NSAppearanceNameVibrantLight); self.appearance = systemAppearance; self.locationManager.startUpdatingLocation(); } } func windowWillClose() { self.locationManager.stopUpdatingLocation(); } }
NSWindowController子类:
import Cocoa class TweetWindowController: NSWindowController { var tweetWindow: TweetWindow { return self.window as! TweetWindow; } override func windowDidLoad() { super.windowDidLoad() self.tweetWindow.initialize() // Implement this method to handle any initialization after your window controller's window has been loaded from its nib file. } override func showWindow(sender: AnyObject?) { self.tweetWindow.windowWillShow() super.showWindow(sender) } }
当然,我也有一个包含我窗口的.xib文件.它被称为“TweetWindow.xib”.
现在,到目前为止,这应该没问题.
在我的AppDelegate.swift中,我执行以下操作:
@NSApplicationMain class AppDelegate: NSObject,NSApplicationDelegate { var tweetWindowController:TweetWindowController!; func applicationDidFinishLaunching(aNotification: NSNotification) { // Insert code here to initialize your application tweetWindowController = TweetWindowController(windowNibName: "TweetWindow"); } func applicationWillTerminate(aNotification: NSNotification) { // Insert code here to tear down your application } func showTweetWindowInternal() { NSApp.activateIgnoringOtherApps(true); tweetWindowController.showWindow(nil); } @IBAction func showTweetWindow(sender: AnyObject) { showTweetWindowInternal(); } @IBAction func quitApp(sender: AnyObject) { NSApplication.sharedApplication().terminate(self); } }
我的问题如下:
当我尝试单击与IBAction相关联的按钮以显示窗口时,会抛出异常:
var tweetWindow:TweetWindow {return self.window as! TweetWindow; }
它说致命错误:在展开Optional值时意外发现nil,因此窗口为零.
为什么那里的窗户没有?我试图过早地获取价值还是什么?
这是一些照片:
谢谢.
所以,是的,在调用super之前,你在showWindow()覆盖中调用self.tweetWindow.windowWillShow()太早了.此时NIB尚未加载,因此窗口插座未连接任何东西.
当然,您必须确保插座实际连接在NIB中,或者即使在加载NIB之后也不会连接.但是在加载之前尝试访问它是第一个问题.
我认为你的windowWillShow()方法是错误的,至少在实现时是这样.窗口可以通过各种方式显示,而不仅仅是窗口控制器的showWindow()方法.例如,窗口和窗口控制器之外的东西可以执行tweetWindowController.window.makeKeyAndOrderFront(nil).如果你真的想做这样的事情,让窗口类重写各种order …()方法,看看窗口是否第一次被订购,如果是,请调用你的方法.
更新:
你的NIB中有几个配置错误的东西.以下是修复它们所需要做的事情:
>将当前连接从文件所有者的“委托”出口断开到窗口.单击您发布的任一屏幕截图中的“x”按钮.>更改文件所有者的类.它目前是TweetWindow.它应该是TweetWindowController.控制器是加载和拥有NIB的,因此File的所有者类应该是控制器类.>将文件所有者的“窗口”插座连接到窗口.>将窗口的“委托”插座连接到文件所有者.