Cocoaのマルチウインドウプログラム作成

注意事項
Cocoaで複数のウインドウを扱うプログラムの作り方が分からず色々なサイトで調べてみたが、ある程度参考になったもののいまいちピンとこなかった。なんとか動くものが作れたのでそれを記載する。

完成イメージ
f:id:nashikachi:20160904225127p:plain

■ウインドウの内容ごとにxibファイルを作成

メインウインドウと全く同じウインドウを作る場合や、メインウインドウ内で画面内容を変える場合は同一のxibを使う。
しかし、全く別のウインドウをマルチに表示させる場合、それ専用のxibファイルを作成しておく必要がある(そうでない方法もあるかもしれない。例えばNSPanelを使ったサブウインドウなど)。

まずMainMenu.xibとは別に、xibを用意する。
xibファイルは、⌘Nで新規ファイル作成画面を開き、
OS X > User Interface > Window を選択して作成する。
今回ファイル名はSubWindow.xibとした。
f:id:nashikachi:20160904225051p:plain

今回は作成したxibに、ラベルを一つだけ設定しておく。
f:id:nashikachi:20160904225056p:plain

■NSWindowControllerのサブクラスを作成

次にNSWindowControllerのサブクラスを作成する。このサブクラスのインスタンスがウインドウとなる。
今回はこのサブクラスに何か追記したりはしないが、ここでメインのxibからデータを引き渡すなどができる。
今回クラス名はSubWindowControllerとした。
●SubWindowController.h

#import <Cocoa/Cocoa.h>

@interface SubWindowController : NSWindowController
@end

●SubWindowController.m

#import "SubWindowController.h"

@interface SubWindowController ()

@end

@implementation SubWindowController

- (void)windowDidLoad {
    [super windowDidLoad];
    
}
@end

■SubWindw.xibの編集

新しく作成したSubWindo.xibの File's Owner の Custom Class に、先ほど作成した SubWindowController を設定する。
f:id:nashikachi:20160904225104p:plain

また、File's Owner の Outlets に Window を設定する。
f:id:nashikachi:20160904225112p:plain

■ウインドウを呼び出す準備

SubWindow.xibのウインドウを呼び出す処理を記載する。
MianMenu.xib のウインドウに、 SubWindow.xib のウインドウを呼び出すボタンと処理を追加する。

ボタンのIBActionを処理するAppContorllerを作成する。ここでは、このAppControllerがSubWindowControllerのインスタンスの保持もすることにする。

●AppController.h

#import <Foundation/Foundation.h>
#import <Cocoa/Cocoa.h>

@class SubWindowController;

@interface AppController : NSObject {
    SubWindowController *subWindowController;
}

- (IBAction) showSubWindow:(id)sender;
@end

●AppController.m

#import "AppController.h"
#import "SubWindowController.h"

@implementation AppController

- (IBAction) showSubWindow:(id)sender
{
    if(!subWindowController) {
        subWindowController = [[SubWindowController alloc] initWithWindowNibName:@"SubWindow"];
    }
    [subWindowController showWindow:self];
}

@end

上記コードの通り、ウインドウを呼び出すのは直接xibのファイル名を指定して呼び出している。
もし呼び出したウインドウを×で閉じた場合、subWindowController変数はnilとなるため、次回もう一度ボタンを押せばウインドウを作成して表示するようになっている。


AppControllerはMainMenu.xibに配置する。
f:id:nashikachi:20160904225119p:plain


あとはボタンとAppControllerの showSubWindowメソッドを接続すれば完成。

■その他の方法

今回はNSWindowControllerのサブクラスとxibを作って呼び出した。
他にも調べた中には、NSWindowControllerではなく NSNib で呼び出す方法もあった。
また、xibすら用意せず、コードの中でウインドウの内容を作っていく方法もあるらしいと分かった。
今のところ、NSWindowControllerのサブクラスとxibで作る方法が一番分かりやすいのではと思う。