这就是我所拥有的:
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的所有者类应该是控制器类.>将文件所有者的“窗口”插座连接到窗口.>将窗口的“委托”插座连接到文件所有者.