2015-04-07 31 views
0

我有一個使用標準模板的基於文檔的應用程序。我在Main Menu.xib中有兩個輔助面板,我的主邏輯當前位於App Delegate中,主要是通過我面板上的按鈕觸發的App Delegate中的IBAction。一切正常,但我知道它應該組織得更好。使用單獨的.nibs並從應用程序代理獲取邏輯

我實現了一個首選項面板由Hillegass第12章所以建議:

  • 創建一個名爲AppController的定製控制器包含PreferenceController實例 。這是在主菜單中實例化的。

  • 定製PreferenceController類,它是 NSWindowController的子類。這會將在Preferences.xib

創建之前,我在應用程序的開發太遠的Preferences.xib

  • 首選項面板,我要確保我組織的事情以正確的方式。

    我想將我的主邏輯從App Delegate移出,可能進入App Controller。我希望App Controller負責顯示和隱藏各種面板,並且我希望每個面板都有自己的.xib。

    我已經創建了兩個NSWindowController的子類,並使它們成爲AppController的ivars,與PreferencesController例如一樣。 Panel1Controller & Panel2Controller。

    我的問題是界面生成器不讓我連接AppController中的一個IBAction到我面板上的一個按鈕。它只允許我連接到.xib文件的所有者,即Panel1.xib的Panel1Controller。

    如果我把邏輯放在Panel1Controller中,我怎麼才能在其他面板之一(比如Panel2Controller?)中隱藏它?

    我對此有何看法?

    變得非常困惑...。

    任何幫助非常感謝!

    問候,

    約翰

  • +0

    爲了能夠在Interface Builder中連線,您需要在Interface Builder中引用目標對象。要做到這一點,將對象庫中的「對象」拖到App Controller的xib文件中。然後將該對象的類設置爲您的「AppController」類。做這件事時要記住的一件事是,當你加載xib時,對象將被自動實例化。 最後,所有的Panel1Controller邏輯都應該在Panel1Controller中。 – markeissler

    回答

    0

    只是爲了簡單起見,我將所有由NSWindowController子類控制筆尖構件出主筆尖進入碎粒具有相同的名稱爲(NSWindowController )控制它們的子類。不要將IBOutlets或IBActions暴露在子類頭中(它們應該在該子類的源文件中的類擴展中(「@interface MyWindowController()」) 另外,AppController是第二個應用程序委託?也許不是你想要的(只能有一個);你應該合併其邏輯到現有的應用程序委託,如果是這樣的話

    +0

    謝謝。我想讓App Delegate與AppController分開。我讀過這是很好的做法。每個.xib都有自己的NSWindowController自定義子類,它也是文件的所有者。麻煩是我看不出如何說,按一個窗口上的按鈕關閉另一個窗口。當一個人不知道另一個人時,他們如何溝通? – jhclare

    +0

    與公共標點對話:應用程序委託([NSApplication sharedApplication] .delegate);它應該知道所有的窗口控制器,它可以告訴他們什麼時候關閉。 – geowar

    +0

    我想避免使用App Delegate來實現NSApplicationDelgate協議方法以外的任何其他功能。我試過從我的AppController類加載.xibs,根本不使用NSWindowController。這可以工作,但窗口不會出現在窗口菜單中。必須有一個標準的方式來做到這一點? – jhclare

    0

    我只是碰到this方法來

    這似乎廢除。 NSWindowController,並使AppController成爲兩個.xibs的文件所有者。這樣,IB允許您在AppController中爲每個窗口創建網點,幷包含操作。

    我使用這種方法創建了一個非常簡單的雙窗口應用程序,當另一個按鈕被按下時,該窗口隱藏一個窗口。在我離開之前重新組織我的主應用程序之前,我想確保我正確地使用這個標準方法,如果有的話?

    This頁面與此方法相矛盾,通過說一個窗口=一個.xib +一個NSWindowController子類。

    如果你用後一種方式來做,當你無法在AppController中創建出口/動作時,一個窗口如何與另一個窗口對話?在窗口的NSWindowController類中實現的操作無法看到另一個窗口的出口,因此它們如何通信?

    這看起來很標準,基本的東西,但我找不到任何來源哪個方式是正確的/最佳實踐。

    +0

    這對簡單的應用程序來說沒問題,但是一旦你變得更加複雜(就像多個窗口具有不同的表格視圖一樣),你將不得不編寫更多的代碼來確定哪個控件調用給定的委託方法等等。每個窗口使用一個窗口控制器。您可以隨時在您的應用程序控制器/代理中添加更多方法。 - (IBAction爲)closeTheOtherWindows:(ID)發送者; – geowar

    +0

    謝謝,我明白了。但是,如何關閉其他Windows作爲插座連接? Interface Builder只允許你將插座連接到.xib文件的所有者,這將是每個窗口的NSWindowController子類。如果每個窗口的插座和動作都封裝在它們各自的NSWindowControllers中,它們如何相互通信? – jhclare

    +0

    是的,不要把它當做IBAction(我的壞話);只是將其作爲(非IBAction)方法來完成。在應用程序控制器(/委託)的頭文件中定義它,它將包含在窗口控制器中。然後,一個IBAction方法將在應用程序控制器(/委託)中調用(非IBAction)方法。 – geowar

    0

    我讀到的有關使用通知的here提到的另一種方法。

    儘管如此,我仍然想知道哪一種是最常見的「接受」方法,將兩個或多個窗口加載到單獨的.nibs中並讓它們相互通話?我很驚訝這個信息很難找到。

    0

    如果你要遵循這種模式,單獨AppDelegate和AppController,那麼你的MainMenu.xib不應該包含任何類型的窗口對象......它應該只包含應用程序菜單。每個額外的窗口(NSWindow/NSPanel等)都有它自己的.xib和它自己的NSWindowController。

    有兩種方式爲您的屬性(IBOutlets)和方法(IBActions)分配引用:1)通過編程方式,2)通過Interface Builder。我們來介紹第二種方法!

    爲了能夠從Interface Builder(IB)連線,您需要對IB內部的目標對象進行引用。對於MainMenu.xib文件,它會自動設置:MainMenu.xib包含一個「AppDelegate」對象引用。 Object引用公開了AppDelegate類中以「IBAction」和「IBOutlet」宏爲前綴的屬性和方法。我寫對象(大寫),因爲它是IB中的「對象庫」中可用的小部件。

    通過將「對象」小部件從對象庫拖動到.xib中,您可以輕鬆地在.xib文件(通過IB)內創建自定義對象的實例。然後將對象的類設置爲您的自定義類的類。完成此操作後,IB自定義類對象中的IBActions和IBOutlets將可用。 [注意:做這件事時要記住的一件事是,當你加載xib時,對象將被自動實例化。不需要在AppDelegate內部進行分配和初始化......你仍然需要調用showWindow:在它上面]。

    正如您所提到的,另一種方法是簡單地擁有AppController擁有的所有額外的.xib文件。這樣做會很方便,但它也可以從首先嚐試遵循的體系結構中獲得100%的收益。換句話說,如果你要遵循這種風格,爲什麼不首先跳過單獨的AppDelegate和AppController,而只是堅持前者(這將是一個Controller和Delegate)。