2015-10-20 75 views
0

我有一個窗口,其中有一個按鈕。當我點擊按鈕時,它會打開另一個窗口(這兩個窗口都在同一個xib文件中)。我通過將第一個窗口中的按鈕綁定到第二個窗口的orderFront來完成此操作。這按預期工作。 現在我需要一個回調函數(IBAction)在第二個窗口變得可見時觸發(根據第一個窗口中的設置對第二個窗口進行一些更改)。我在第二個窗口的控制器類中有佔位符IBAction,但我似乎無法找到窗口「變得可見」與其綁定的觸發器。 奇怪的是,在任何地方都可以看到NSWindow的回調函數(谷歌搜索)。這些東西是通過.NET和Visual Studio中的點擊完成的(我從.NET移植代碼)。我是否在談論這個完全錯誤的東西?IBAction窗口變得可見OS X

回答

1

我會說是的,從標準Cocoa設計的角度來看,你試圖對它做一些錯誤的處理,原因有兩個。很抱歉,很長時間以來,在概念層面上有很多需要解決的問題。首先,當你想知道特定事物發生在特定對象上時,目標/動作機制並不是Cocoa中的標準方式,除非「事情正在發生」是直接的用戶操作,例如點擊。你用一個按鈕的動作來顯示一個窗口的方式很好,這是用戶發起的(按下按鈕),所以一個動作是適當的。但要知道第二個窗口已改變狀態(變得可見),使用(1)委派或(2)通知更爲典型。這兩個都很有用;在Apple的文檔中閱讀它們(我相信Google會幫助你)。例如,您可以聲明一個對象作爲第二個窗口的委託,當窗口變爲關鍵或主要時,它會接收到消息,當它更改屏幕,關閉時等。 - 無論您感興趣的狀態更改

但是,這裏還有第二個轉折點。如果您查看NSWindowDelegate協議的文檔,您將看到諸如windowShouldClose:windowWillClose:之類的代理方法,但沒有相應的方法,如windowDidOpen:windowDidOrderIn:。有一些代表方法可能適用於您,具體取決於您在做什麼,如windowDidBecomeKey:windowDidBecomeMain:,或者甚至可以是windowDidExpose:,但不是windowDidOpen:或類似。我認爲,蘋果給你發了一條消息:你的代碼真的不應該在意。所以你不應該使用windowDidBecomeKey:等,除非他們確實代表你感興趣的事件 - 聽起來他們沒有。相反,你應該更深入地思考蘋果告訴你什麼,不包括windowDidOpen:消息。爲什麼他們會留下這樣一個明顯的委託信息?

這是我的答案。您的第二個窗口已被加載,因爲它與第一個窗口位於同一個筆尖。不管是否可見,在任何時候,都是一個細節,明智的做法是避免對蘋果的代表設計進行假設,這就是我所推測的原因。該窗口可能會通過窗口恢復自動顯示;它可能來自於應用程序代碼之外的某些內容,例如Exposé或Spaces等技術或蘋果下一步要做的任何事情;你可以讓你的代碼在不同的地方看到你自己的窗口。您無需擔心這些細節,只需在代碼最後一分鐘設置窗口,然後才能看到正確的窗口。如果一個窗口在窗口列表中,在大多數情況下,不管它是否可見,都不應該成爲代碼的關注點;窗戶應該保持良好的狀態,這樣它很高興在沒有任何需要臨時修正的情況下顯示。根據蘋果的設計,你的代碼應該擔心窗口首先從筆尖創建的時刻,並將其設置爲正確的狀態 - awakeFromNib就是爲此 - 關於窗口關閉的時刻(因爲通常情況下,儘管並非總是,窗戶在關閉時不再存在,因此需要清理) - windowWillClose:就是這樣。在這之間,你的窗戶應該保持良好的狀態。這樣做的工作應該是非常小的,因爲除非窗口實際上在屏幕上,否則所有圖形都將被抑制。

所以,當你寫「你想根據第一個窗口中的設置對第二個窗口進行一些更改」時,正確的設計很可能是立即在第二個窗口中做出這些更改以響應第一個窗口發生。通過連接到任何用戶界面正在改變的操作檢測第一個窗口中的更改,並響應這些操作更改第二個窗口。然後,當第二個窗口顯示時,你的代碼甚至不需要知道。這是一個更清潔的設計;這意味着,例如,如果第一個窗口在顯示第二個窗口後進一步改變,第二個窗口將自動對這些改變作出反應,而「在顯示之前修正第二個窗口」設計不會達到。

如果這看起來不適合您在應用程序中要做的事情,那麼您需要更具體地瞭解您要實現的目標。我認爲一般來說這是根據Cocoa的邏輯設計的正確設計,如果兩個窗口都在同一個筆尖中,則爲。如果它看起來對你來說是錯誤的設計,那麼這幾乎可以肯定地表明第二個窗口實際上不應該與第一個窗口在同一個筆尖中,並且應該爲第二個窗口加載一個新的筆尖,導致第二個窗口由控制器配置,該控制器在加載完筆尖之後爲第二個窗口加載筆尖。 (或通過第二窗口單獨的控制器,也可能由第二窗口本身在其awakeFromNib;這裏還有不少的選擇取決於你的架構。)

我會勸你通過繼承來破解這NSWindow作爲另一個答案已經提出(答案,現在刪除,建議繼承和覆蓋一種方法,如makeKeyAndOrderFront:以或多或少地破解windowDidOpen:種功能)。出於某種原因,Apple忽略了windowDidOpen:委託消息;如果這只是一種心不在焉的疏忽,它會在很多年前加入。 Cocoa編程的關鍵是要學會不打蘋果。可可一般是一個非常精心設計的框架(雖然有一些例外的類: - >),如果你學會了使用它而不是與之對抗,那麼你的生活將會更容易。

+1

我刪除了我的答案,你說得對。 – Moritz

+0

我試圖避免立即更改第二個窗口的原因是......第一個窗口中的組合框選擇一個*函數*,用戶可以*在其中應用*,並涉及大量計算。用戶還可以選擇*修改*功能* - 在第二個窗口中。問題是確定如何設置第二個窗口本身也涉及繁重的字符串解析。所以我只是試圖避免在設置第二個窗口時浪費計算,當用戶嘗試*應用*函數並且無意修改它時。但是現在我只想跟你的建議一起使用 – Hashman

+0

聽起來就像你可能希望第二個窗口在一個單獨的nib中,當該nib被加載時配置。 – bhaller