Суть построения View-based таблицы заключается в том, чтобы вместо обычных строк, состоящих из
NSImageView и
NSTextField (как показано в предыдущем
примере), создать кастомную (свою модель компонентов в строке) строку. И здесь как всегда на помощь приходит
NSView, а точнее
NSViewController - класс.
Создаем новый проект. Назовем его
ViewBasedNSTableViewWithNSView (Вы можете его назвать по своему, суть этого не меняется). Как и в предыдущем
примере добавим таблицу, сделаем строку View-based (прочтите предыдущий пример, здесь в этом посте я упущу эти тонкости). Далее добавим новый класс наследуемый от
NSViewController c xib-формой. Добавим компоненты интерфейса на xib-форму. Я добавил два Label, кнопку с изображением ImageCell и ProgressBar. Т.е. можно накидать компоненты по своему желанию и усмотрению, а также целевому типу. Должно получится что-то из этого:
В ViewController.h сделаем оутлеты к нашим компонентам и к самой вьюхе и парочку методов.
#import <Cocoa/Cocoa.h>
@interface ViewController : NSViewController {
IBOutlet NSImageView *iconView;
IBOutlet NSTextField *messageLabelOne;
IBOutlet NSTextField *messageLabelTwo;
NSView *_mainView;
}
- (void) setStringValueForFirstTextFields: (NSString *) stringValue;
- (void) setStringValueForSecondTextFields: (NSString *) stringValue;
- (void) setIconForRowOnView: (NSImage *) iconContent;
@end
В ViewController.m распишем код для наших методов, также по умолчанию зададим текст для лэйблов:
#import "ViewController.h"
@interface ViewController ()
@end
@implementation ViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Initialization code here.
}
return self;
}
- (id)init {
[self.view addSubview: _mainView];
[messageLabelOne setStringValue:@"Message One"];
[messageLabelTwo setStringValue:@"Message Two"];
return self;
}
- (void) setStringValueForFirstTextFields: (NSString *) stringValue {
[messageLabelOne setStringValue:stringValue];
}
- (void) setStringValueForSecondTextFields: (NSString *) stringValue {
[messageLabelTwo setStringValue:stringValue];
}
- (void) setIconForRowOnView: (NSImage *) iconContent {
[iconView setImage:iconContent];
}
@end
Подключим хидер контроллера-модели ячейки в AppDelegate.h. Объявим массив в котором будем хранить вьюхи-объекты, свяжем оутлет переменной
NSTableView с таблицей на форме, добавим объект-контроллер (по которому будем обращаться к индексу массива объектов и получать наш объект для текущего индекса строки. Помните?, я уже упоминал что строки в таблицу добавляются строчка-за-строчкой.).
#import <Cocoa/Cocoa.h>
#import "ViewController.h"
@interface AppDelegate : NSObject <NSApplicationDelegate, NSTableViewDelegate, NSTableViewDataSource> {
NSMutableArray *objArray;
ViewController *vController;
}
@property (assign) IBOutlet NSWindow *window;
@property (weak) IBOutlet NSTableView *tableView;
@end
Дальше будем создавать объекты, задавать им соответствующие иконки и значения лэйблам, помещать в массив и дальше дело техники делегированных методов
NSTableView.
#import "AppDelegate.h"
@implementation AppDelegate
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
// Insert code here to initialize your application
}
- (void)awakeFromNib {
objArray = [[NSMutableArray alloc] init];
ViewController *oneController = [[ViewController alloc] init];
ViewController *twoController = [[ViewController alloc] init];
ViewController *treeController = [[ViewController alloc] init];
ViewController *fourController = [[ViewController alloc] init];
ViewController *fiveController = [[ViewController alloc] init];
ViewController *sixController = [[ViewController alloc] init];
ViewController *sevenController = [[ViewController alloc] init];
[oneController setStringValueForFirstTextFields:@"Hello World"];
[oneController setStringValueForSecondTextFields:@"Hello To You"];
[oneController setIconForRowOnView:[NSImage imageNamed:@"layers.icns"]];
[twoController setStringValueForFirstTextFields:@"Hello World"];
[twoController setStringValueForSecondTextFields:@"Hello To You"];
[twoController setIconForRowOnView:[NSImage imageNamed:@"Slice 1.icns"]];
[objArray addObject:oneController];
[objArray addObject:twoController];
[objArray addObject:treeController];
[objArray addObject:fourController];
[objArray addObject:fiveController];
[objArray addObject:sixController];
[objArray addObject:sevenController];
}
- (NSInteger)numberOfRowsInTableView:(NSTableView *)tableView {
return [objArray count];
}
- (id)tableView:(NSTableView *)tableView viewForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row {
vController = [objArray objectAtIndex:row];
return [vController view];
}
@end
Должна получится вот такая каша:
В принципе все. Самое главное - это понять как работает делегирование в таблице и сама таблица. Все остальное дело техники. При моей занятости (работа, семья) на понимание всей этой каши (по работе с таблицами в целом) ушло месяц-полтора. Если посчитать время уделенное на разборку всего этого, то общая затраченная сумма при интенсивном изучении заняла бы всего-то меньше недели.
Продолжение