2009-06-20 13 views
3

作爲Cocoa的新手,我很努力地理解泛型NSResponder子類爲什麼按照他們似乎要做的方式實現關鍵事件。爲什麼NSWindow或NSView實例處理自己的關鍵事件,而不是它的委託?

在我的程序中,我有一個NSWindow子類,它佔用整個屏幕,並且必須處理關鍵事件。有幾個主要的命令可以改變整個程序的狀態(例如,當用戶點擊空格鍵時暫停一個定時器),而像NSTextField句柄這樣的子視圖是沒有意義的。

在我看來,代表(控制器)應該得到這些事件。相反,我發現我必須寫一大堆凌亂的膠水代碼才能讓窗口(通過它的keyDown:interpretKeyEvents:選擇器)通知控制器,否則我必須將一堆控制器代碼移到NSWindow子類本身。

這很混亂,我的直覺告訴我我錯過了一些東西。有更清潔的解決方案嗎?

回答

4

如果您設置正確,NSWindow的代表將收到消息。 Cocoa使用響應者鏈轉發來自第一響應者的消息 - 關鍵消息的關鍵視圖以及被點擊/徘徊的視圖等。用於鼠標消息 - 回顧超級視圖,透過窗口,最終到達窗口的代表。在Apple's site上有典型的響應者鏈的相當好的圖表。

除非你正在實現一些花哨的窗口繪圖或其他沿着這些線的其他東西,否則你真的不應該繼承NSWindow的子類。可可提供NSWindowController類作爲窗口及其內容的控制器。

通常的模式是子類NSWindowController並添加您的IBOutlet s,然後使用NIB來佈置您的窗口內容。在Interface Builder中,您使NSWindowController子類成爲文件所有者代理的類。並且您還將窗口的delegate分配給窗口控制器,以便它可以成爲響應者鏈的一部分。最後,要創建窗口,請使用NSWindowControllerinitWithWindowNibName:方法,該方法使用新的窗口控制器作爲文件的所有者自動加載NIB。

我建議您閱讀Cocoa文檔中的窗口控制器,因爲它們提供您正在尋找的缺失鏈接。

+0

我的委託實際上是一個NSWindowController子類。我沒有使用Interface Builder,因爲我試圖創建一個在其實例化時可能無邊界的窗口,並且IB似乎不允許這樣做 - 此外,我試圖瞭解詳細信息和IB隱藏了很多,所以我認爲這個應用程序值得學習「硬道路」。 感謝您鏈接到文檔的該部分。我讀過它,但錯過了關於NSWindowController是最後一招的詳細信息。很明顯,我在管理響應者鏈上犯了一些錯誤。 – EricB 2009-06-20 21:07:17

相關問題