Nie jestem pewien, czy jest dużo wglądu w tworzenie widoku kolekcji programowo i bez powiązań, ale tutaj jest.
Wprowadzenie
Istnieją zasadniczo cztery składniki przy użyciu widoku kolekcji:
- Widok: podklasę
NSView
, odpowiedzialnego za wyświetlanie informacji;
- Sam widok kolekcji;
- Kontroler widoku: podklasa o numerze
NSCollectionViewItem
, która służy jako prototyp pozycji widoku kolekcji;
- Model: tablica obiektów.
Zwykle widok jest projektowany w Konstruktorze interfejsów, a model jest za pośrednictwem wiązań kakao.
Robi to programowo:
Stałe
static const NSSize buttonSize = {80, 20};
static const NSSize itemSize = {100, 40};
static const NSPoint buttonOrigin = {10, 10};
Zobacz
Jest to standardowy widok (widok niestandardowy interfejs Builder w żargonie) zawierający przycisk. Zwróć uwagę, że widok ma ustalony rozmiar.
@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 (prototyp)
Normalnie kontroler widoku ładuje swój pogląd z pliku nib. W rzadkich przypadkach, gdy kontroler widoku nie uzyskuje widoku z pliku nib, programista musi albo wysłać go pod numer -setView:
, zanim -view
zostanie odebrany przez kontroler widoku, albo zastąpić -loadView
. Poniższy kod wykonuje to drugie.
Wyświetl kontrolery otrzymujące odpowiedni obiekt modelu poprzez -setRepresentedObject:
. Zastąpiłem go, aby zaktualizować tytuł przycisku za każdym razem, gdy zmienia się obiekt modelu. Zauważ, że można to osiągnąć za pomocą wiązania kakao bez żadnego kodu.
Należy zauważyć, że żaden z tych kodów nie jest specyficzny dla widoków kolekcji - jest to ogólne zachowanie kontrolera widoku.
@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
model
prostą tablicę ciągów reprezentujących tytuły przycisk:
@property (strong) NSArray *titles;
self.titles = [NSArray arrayWithObjects:@"Case", @"Molly", @"Armitage",
@"Hideo", @"The Finn", @"Maelcum", @"Wintermute", @"Neuromancer", nil];
Collection Zobacz
Dotychczas tylko relacja, która została założona jest pogląd (BVView
) używane przez prototyp przedmiotu (BVPrototype
). Widok kolekcji musi być poinformowany o prototypie, który powinien zostać użyty, jak również modelu, z którego należy uzyskać dane.
NSCollectionView *cv = [[NSCollectionView alloc]
initWithFrame:[[[self window] contentView] frame]];
[cv setItemPrototype:[BVPrototype new]];
[cv setContent:[self titles]];
Pełny kod źródłowy aplikacji Delegata
#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
Dokumentacja na NSCollectionView jest zaskakująco słaba. Każdy, kto rozumie, w jaki sposób ta mityczna bestia działa i może dzielić się swoją wiedzą, pomaga deweloperom Objective-C wszędzie. Dzięki wielkie. – Tronathan
Bawarii, czy mogę prosić o pokazanie, jak zsynchronizować widok kolekcji z zmienną tablicą elementów? – brigadir
@Barious - dzięki za wspaniałą odpowiedź. –