我不确定在没有绑定的情况下以编程方式创建集合视图是否有很多见解,但它就在这里。
介绍
使用集合视图时基本上有四个组件:
- 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
视图控制器(原型)
通常,视图控制器从 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