(前回)Cocoaの日々: NSViewController
リファレンスによれば NSViewController は通常 nibファイルから読み込まれるとある。
An NSViewController object manages a view, typically loaded from a nib file.
Mac Dev Center: NSViewController Class Reference
前回紹介したサンプルもだいたいそんなかんじだった。前回のコードを変更して試してみよう。
nibファイルの作成
新しく空の nibファイル を作成する。
前回作ったカスタムビューをコピーする。
File's Owner のクラスを(同じく前回用意した)ViewController に設定する。
イメージとテキストフィールドの Bindings の Value を File's Owner の representedObject へバインドする。
File's Owner の接続はこんな感じ。
nib 経由の NSViewController 作成
前回アウトレット経由で取得していた ViewController へのリファレンスを、nib経由に変更する。追加したのは1行だけ(太字)。
AppController.m
@implementation AppController
- (void)awakeFromNib
{
imageFile = [[ImageFile alloc] init];
imageFile.image = [NSImage imageNamed:@"sample"];
imageFile.name = @"sample.jpg";
imageFile.date = [NSDate date];
viewController = [[NSViewController alloc]
initWithNibName:@"SampleView" bundle:nil];
[viewController setRepresentedObject:imageFile];
[view addSubview:[viewController view]];
}
@end
これだけOK。
実行してみよう。
出た。
ソースコード
githubからどうぞ
xcatsan's SampleCode at 2009ViewControllerStudy at 20091120 from xcatsan's SampleCode - GitHub1120 - GitHub
考察
イメージを描いてみた。
こうすると NSViewController の役割が(多分)よくわかる。
NSViewController は View と Model の間を取り持つ役割を果たしている。View から見るとModelの実装が隠されていて、表示に必要な情報を得るには(あるいは保存するには) NSViewController が提供する representedObject だけを見れば(bind)良い。言い換えると開発時にViewの制作者はModelの実装を知る必要ことなくコントロールを配置や設定に専念することができる。お互いに実装が隠されることで Model の変更が View へ与える影響は少なく、その逆の場合も影響は少ない。
また nib に NSViewController を入れることでコンポーネント的な扱いができるようにもなる。複数並べたり、別のプロジェクトでも使い回せるということ。利用する側は nib を読み込み reprsentedObject と Model を紐づけるだけで良い。一旦紐づければ後は Cocoa bindings が働いて、コードを書かなくとも View と Model の同期が自動的に行われる。NSCollectionView ではまさに NSCollectionViewItem(NSViewControllerのサブクラス)をこの目的で使っている。
試しに先ほどのサンプルに手を加え NSViewController を複数作成して配置してみた。これを発展させれば NSCollectionView のようなものが作れるだろう。
#ただ大量にビューを並べると様々なリソースを食い過ぎるので工夫が必要だと思われる。
複数並べた版のソースコード:
ViewControllerStudy at 20091120-2 from xcatsan's SampleCode - GitHub