Позвоните в IBAction в другом классе - PullRequest
1 голос
/ 10 июня 2011

У моего приложения на основе документов есть окно с табличным представлением. Табличное представление имеет источник данных, который указывает на класс типа NSObject (называемый HopBill), который включает в себя NSMutableArray (aHopBill) и необходимые методы табличного представления. Пока все хорошо.

Для добавления строк в табличное представление я добавил лист, который управляется из NSWindowController (называемого HopBillSheetController). При нажатии кнопки ОК на листе. На самом деле мне нужно сделать два IBActions (что невозможно): добавить строку в массив таблицы и закрыть лист. Я могу подключить кнопку OK на листе к NSWindowController (чтобы закрыть лист) или подключить его к NSObject (чтобы добавить строку в массив). Но я хочу оба: -)

Можно ли вызвать IBAction в NSWindowController из NSObject? Или есть другой способ сделать это?

Я довольно новичок в Cocao и Objective-C, поэтому, пожалуйста, будьте осторожны: -)

Ответы [ 2 ]

1 голос
/ 11 июня 2011

Если ваш лист представляет собой перо / сгиб с панелью NSPanel, вызов для его закрытия просто [закрытие панели]; Предполагая, что у вашего оконного контроллера есть свойство для панели, вы можете поместить код закрытия в конец его IBAction с добавлением строк. Или вы можете сами вызывать IBAction для вызова другого метода.

Если ваша панель работает модально, вам, возможно, придется остановить StopModal. (Это то, что нужно, если все останется замороженным после закрытия панели; иначе не обращайте внимания.)

Предполагая, что hopBill, ваш источник данных, является свойством оконного контроллера, любой IBAction, который вы пишете в оконном контроллере, также имеет доступ к hopBill; он может делать все, что вам нужно.

Поэтому добавьте один IBAction к оконному контроллеру и подключите к нему кнопку OK на панели. Это должно сработать.

Что касается вызова IBAction откуда-то, кроме элемента управления в перо, да, вы можете это сделать. Использовать ссылку на элемент управления в качестве аргумента отправителя или nil, если IBAction не использует аргумент отправителя.

Вы также можете создать свою панель программно или использовать NSAlert. Но, похоже, ваша текущая настройка проще - и, следовательно, лучше.


Посмотрите на этот h-файл для контроллера приложения: Пример Apple's ClockControl

Свойство назначений NSMutableArray * - это фактический источник данных, который будет использоваться методами протокола NSTableViewDataSource. IBAction "addAppointment" может напрямую обращаться к "встречам": [self.appointments addObject: что угодно, atIndex: что угодно];

Пример ClockControl может быть изменен для использования HopBill. Вы должны импортировать его объявления вверху: #import "HopBill.h" И затем вместо свойства "назначений" он объявит HopBill * hopBill; И «addApointment» получит доступ к изменяемому массиву HopBill (aHopBill) следующим образом: [self.hopBill.aHopBill addObject: что угодно atIndex: что угодно];

0 голосов
/ 12 июня 2011

Почему вы не можете отправлять сообщения на hopBill:

Во-первых, потому что, хотя вы объявляете это, вы никогда не инициализируете это. У вас есть:

HopBill *hopBill;
[self.hopBill.aHopBill addObject: bHopAdditionAtInit];

Должно быть:

HopBill *hopBill = [[HopBill alloc] init];
[hopBill.aHopBill addObject: bHopAdditionAtInit]; // “self” won’t work here

Во-вторых, вы объявляете его внутри метода IBAction (doneHopBillSheet :), так что это локальная переменная, доступная только в этом методе. Если HopBill содержит кэш источника данных вашей таблицы, это должно быть свойство контроллера, который реализует методы NSTableViewDataSourceProtocol.

В своем интерфейсе HopBill вы объявляете массив aHopBill как свойство и инициализируете его в методе init HopBill (вы должны также освободить его в методе dealloc HopBill). Вы должны сделать то же самое для контроллера - у него должен быть экземпляр HopBill в качестве свойства, и этот экземпляр должен быть инициализирован в методе init контроллера.

Если вы хотите, чтобы HopBillController управлял табличным представлением, его объявление интерфейса должно выглядеть следующим образом:

@interface HopBillSheetController : NSWindowController <NSTableViewDelegate, NSTableViewDataSource> {
…
}

И, конечно, вам необходимо реализовать соответствующие методы NSTableViewDelegate и NSTableViewDataSource.

Кроме того, контроллер должен иметь свойство IBOutlet для самого представления таблицы, а в методе контроллера awakeFromNib он должен назначить себя в качестве делегата и источника данных:

[self.tableview setDelegate:self];
[self.tableview setDataSource:self];

(Синтаксис собственной точки предполагает, что вы настроили код @property и @synthesize для просмотра таблицы.)

Метод IBAction, который добавляет элементы в вашу таблицу, должен находиться в этом классе контроллера или в классе, у которого есть свойство, которое является экземпляром класса контроллера. Затем метод IBAction получит доступ к массиву aHopBill и сможет добавить новый объект в массив, после чего он вызовет [tableView reloadData], что, в свою очередь, вызовет методы протокола tableview и обновит таблицу.

Теперь, это означает, что xib, содержащий представление таблицы, должен иметь контроллер в качестве владельца своего файла. Поскольку вы используете NSDocument, я подозреваю, что вместо этого вы бы поместили выход табличного представления в подкласс NSDocument. И вы бы дали этому подклассу doc свойство, которое является экземпляром контроллера. Методы IBAction также будут находиться в подклассе doc, и поэтому они будут иметь доступ к контроллеру и его свойству HopBill. Или, может быть, вы просто сделаете doc подклассом контроллера, а не используете отдельный класс HopBillSheetController. Я не уверен насчет NSDocument. Но помните, что метод IBAction может сам вызывать другие методы, если он имеет доступ к экземплярам классов, в которых эти методы объявлены.

В Apple есть пример использования методов делегирования табличного представления и протокола источника данных. Перейдите по этой ссылке и загрузите пример кода: пример таблицы

Это выглядит как хорошее приложение. Удачи.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...