コレクション ビューをプログラムでバインドせずに作成することについて、あまり洞察があるかどうかはわかりませんが、ここでは説明します。
序章
コレクション ビューを使用する場合、基本的に 4 つのコンポーネントがあります。
- View: のサブクラスで
NSView
、情報の表示を担当します。
- コレクション ビュー自体。
NSCollectionViewItem
ビュー コントローラー:コレクション ビュー アイテムのプロトタイプとして機能する のサブクラス。
- モデル: オブジェクトの配列。
通常、ビューは Interface Builder で設計され、モデルは Cocoa バインディングによって仲介されます。
プログラムでそれを行う:
定数
static const NSSize buttonSize = {80, 20};
static const NSSize itemSize = {100, 40};
static const NSPoint buttonOrigin = {10, 10};
意見
これは、ボタンを含む標準ビュー (Interface Builder 用語でのカスタム ビュー) です。ビューのサイズは固定されていることに注意してください。
@interface BVView : NSView
@property (weak) NSButton *button;
@end
@implementation BVView
@synthesize button;
- (id)initWithFrame:(NSRect)frameRect {
self = [super initWithFrame:(NSRect){frameRect.origin, itemSize}];
if (self) {
NSButton *newButton = [[NSButton alloc]
initWithFrame:(NSRect){buttonOrigin, buttonSize}];
[self addSubview:newButton];
self.button = newButton;
}
return self;
}
@end
ビューコントローラー(プロトタイプ)
通常、View Controller はそのビューを nib ファイルからロードします。ビュー コントローラが nib ファイルからビューを取得しないまれなケースでは、開発者はビュー コントローラが を受信する-setView:
前にそれを送信するか-view
、オーバーライドする必要があります-loadView
。次のコードは後者を行います。
ビュー コントローラは、 を介して対応するモデル オブジェクトを受け取ります-setRepresentedObject:
。モデル オブジェクトが変更されるたびにボタンのタイトルを更新するようにオーバーライドしました。これは、コードをまったく使用せずに Cocoa バインディングを使用することで実現できることに注意してください。
このコードは、コレクション ビューに固有のものではないことに注意してください。これは、一般的なビュー コントローラーの動作です。
@interface BVPrototype : NSCollectionViewItem
@end
@implementation BVPrototype
- (void)loadView {
[self setView:[[BVView alloc] initWithFrame:NSZeroRect]];
}
- (void)setRepresentedObject:(id)representedObject {
[super setRepresentedObject:representedObject];
[[(BVView *)[self view] button] setTitle:representedObject];
}
@end
モデル
ボタンのタイトルを表す文字列の単純な配列:
@property (strong) NSArray *titles;
self.titles = [NSArray arrayWithObjects:@"Case", @"Molly", @"Armitage",
@"Hideo", @"The Finn", @"Maelcum", @"Wintermute", @"Neuromancer", nil];
コレクション ビュー
これまでのところ、確立された唯一の関係はBVView
、アイテム プロトタイプ ( BVPrototype
) によって使用されるビュー ( ) です。コレクション ビューには、使用する必要があるプロトタイプと、データを取得するモデルを通知する必要があります。
NSCollectionView *cv = [[NSCollectionView alloc]
initWithFrame:[[[self window] contentView] frame]];
[cv setItemPrototype:[BVPrototype new]];
[cv setContent:[self titles]];
アプリケーション デリゲートの完全なソース コード
#import "BVAppDelegate.h"
static const NSSize buttonSize = { 80, 20 };
static const NSSize itemSize = { 100, 40 };
static const NSPoint buttonOrigin = { 10, 10 };
@interface BVView : NSView
@property (weak) NSButton *button;
@end
@implementation BVView
@synthesize button;
- (id)initWithFrame:(NSRect)frameRect {
self = [super initWithFrame:(NSRect){frameRect.origin, itemSize}];
if (self) {
NSButton *newButton = [[NSButton alloc]
initWithFrame:(NSRect){buttonOrigin, buttonSize}];
[self addSubview:newButton];
self.button = newButton;
}
return self;
}
@end
@interface BVPrototype : NSCollectionViewItem
@end
@implementation BVPrototype
- (void)loadView {
[self setView:[[BVView alloc] initWithFrame:NSZeroRect]];
}
- (void)setRepresentedObject:(id)representedObject {
[super setRepresentedObject:representedObject];
[[(BVView *)[self view] button] setTitle:representedObject];
}
@end
@interface BVAppDelegate ()
@property (strong) NSArray *titles;
@end
@implementation BVAppDelegate
@synthesize window = _window;
@synthesize titles;
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
self.titles = [NSArray arrayWithObjects:@"Case", @"Molly", @"Armitage",
@"Hideo", @"The Finn", @"Maelcum", @"Wintermute", @"Neuromancer", nil];
NSCollectionView *cv = [[NSCollectionView alloc]
initWithFrame:[[[self window] contentView] frame]];
[cv setItemPrototype:[BVPrototype new]];
[cv setContent:[self titles]];
[cv setAutoresizingMask:(NSViewMinXMargin
| NSViewWidthSizable
| NSViewMaxXMargin
| NSViewMinYMargin
| NSViewHeightSizable
| NSViewMaxYMargin)];
[[[self window] contentView] addSubview:cv];
}
@end