В предыдущей статье о View-based NSTableView на основе ячеек из NSView не было реализации по использованию кнопки на виде (замечание в комментарии читателя). Порывшись в поиске (вместе с несуразными лексическими словосочетаниями), хоть какого-то решения так и не было найдено. Было решено использовать делегат и дать право AppDelegate кликать на эту злосчастную кнопку.
Все бы ничего, но как узнать индекс этой чертовой вьюхи, на которой находится эта кнопка? Подумав, поломав голову вместе с мозгами, решил по нажатию кнопки AppDelegate-м передавать ему эту вьюху. Ведь все они разные, т.к. под каждую строку выделена память, естественно и адреса их будут разные.
Создаем делегат - добавляем в проект новый protocol-файл. Объявим в нем метод который будет передавать право тыканья этой кнопки AppDelegate-у.
#import <Foundation/Foundation.h>
@protocol ButtonControllerProtocol <NSObject>
@required
- (void) viewButtonClicked: (NSButton *) clickedButton view: (NSView *) viewCell;
@end
Далее в ViewController.h добавим экшен на кнопку, подключим AppDelegate и укажем какой метод использовать при нажатии этой кнопки.
- (IBAction)buttonInfo:(id)sender {
AppDelegate *myAppDelegate = (AppDelegate *)[[NSApplication sharedApplication] delegate];
[myAppDelegate viewButtonClicked:sender view:[self view]];
}
В AppDelegate.h подключим созданный протокол и пропишем делегат:
#import "ButtonControllerProtocol.h"
@interface AppDelegate : NSObject <NSApplicationDelegate, NSTableViewDelegate, NSTableViewDataSource, ButtonControllerProtocol> {
Реализуем протокольный метод:
- (void)viewButtonClicked: (NSButton *) clickedButton view: (NSView *) viewCell {
NSLog (@"click");
}
Все бы хорошо, метод обрабатывается, выдает определенный результат, а дальше-то что? А дальше нам якобы нужно как-то менять данные на вьюхе. Вот здесь-то и пришлось помучатся. Хотя все оказалось немного проще. Мы помним что окно как главный вид, состоит из подвидов разной сложности, т.е. проще говоря на нашей вьюхе-подвиде тоже есть подвиды (subviews) - nsimageview, nstextfield и т.д. Остается лишь получить к ним доступ. Получим подвиды на вьхе-строке:
Загоним эти объекты в массив и потом создадим указатели на эти объекты и будем обращаться к непосредственно новым объектам-подвидам:
- (void)viewButtonClicked: (NSButton *) clickedButton view: (NSView *) viewCell {
// Получаем строку-вид в нашей таблице
NSView *clickedView = [clickedButton superview];
// Получаем список подвидов в строке-виде
NSArray *viewObjectsArray = [NSArray arrayWithArray:[clickedView subviews]];
// Коннектимся к подвиду и задаем значение
NSImageView *viewObjectImage = [viewObjectsArray objectAtIndex:0];
[viewObjectImage setImage:[NSImage imageNamed:@"Slice 1"]];
NSTextField *viewObjectFirstTextField = [viewObjectsArray objectAtIndex:1];
[viewObjectFirstTextField setStringValue:@"Slice 1"];
}
Вот такое вот нетривиальное, не претендующее ни на что, решение. Если есть более человеческое решение - прошу указать в комментариях.
Отлично сработано! Единственное нужно учесть, что при создании interface порядок внесения элементов nsimageview, nstextfield, nsbutton и т.п. будет влиять на расположение элементов в массиве viewObjectsArray.
ОтветитьУдалитьСпасибо. Да, так и есть - при добавлении нового компонента на вьюху, порядок может немножко изменится. Но это не смертельно. Просто потратится некоторое время (один раз) на анализ порядка и идентификации этих объектов.
Удалить